20140409

Arduino里的Split

overcast Mood at 02:47 AM

其实也不是好久木有写代码,后面都在折腾Arduino玩。初学之后发现类C语言框架里面各种变量声明,各种坑爹的复杂变量类型转换。最狗血的是居然没有自带Split。找了谷哥和度娘很久,翻了近30多页都没有满意的答案。

坑爹的经过大致是这样的:

  1. 要给指纹门禁升级,需要做LCD2004的文字显示。
  2. 在做LCD2004的时候文字满一行不会自动换行,直接除以20来显示,又觉得丑得掉渣。
  3. 打算自己写一个英文分词换行显示的代码。
  4. 写着写着发现分词首先要用到的就是split,结果arduino木有。
  5. 网上搜出来的没有可配置的函数化。
  6. 函数化以后发现返回值打印会经常有溢出的情况(具体至今未知道原因)
  7. 函数化以后发现返回值是数组供调用的时候发现只是传出来两个值
  8. 周旋于string、char、char*……各个类型中间
  9. 最后用函数来模拟数组调用,虽然有点二但至少满足了需求。

所以最后提供大家参考的代码如下:

void setup(){
Serial.begin(9600);
}

void loop(){
char string[] = "Here; is some; sample;100;data;1.414;1020";
int stringnum = splitNum(string, ";");
Serial.print("stringnum=");
Serial.println(stringnum);
for (int i = 0; i < stringnum; i++) {
String tmp = split(string, ";", i);
Serial.print(i);
Serial.print("=");
Serial.println(tmp);
}
Serial.println("------"); delay(5000); }
//ALib Begin//
/*---------------------------------------------------
经历无数次的坑爹,自己乱写的一些库函数。
---------------------------------------------------*/
int splitNum(char* string, char* word) {
int strarrlen = 0;
char *str;
char* stringList;
strcpy(stringList, string);
while ((str = strtok_r(stringList, word, &stringList)) != NULL) strarrlen++;
return strarrlen;
}
String split(char* string, char* word, int splitnum) {
int strstep = 0;
int commaPosition = 0;
char *str;
String stringSplit = string;
String stringTemp;
do {
commaPosition = stringSplit.indexOf(word);
if (commaPosition != -1 && stringSplit.length() > 0) {
stringTemp = stringSplit.substring(0, commaPosition);
stringSplit = stringSplit.substring(commaPosition + 1, stringSplit.length());
if (strstep == splitnum) return stringTemp;
strstep += 1;
}else if (commaPosition == -1 && stringSplit.length() > 0) {
return stringSplit;
} else {
return "Error";
}
}
while (commaPosition >= 0);
}
//ALib End//

写得不好大家多多海涵,也欢迎大家加我QQ或者email我进行交流与改进。

后面公司写C的同学又帮我整了一段,我两也相互扯了些C和js差异什么的……于是有了下面的新代码。

void setup() {
Serial.begin(9600);
}
void loop() {
char string[] = "Here; is some; sample;100;data;1.414;1020";
char** stringarr;
int arrayCount = 0;
stringarr = cSplit(string, ';', &arrayCount);
for (int i = 0; i < arrayCount; i++) {
Serial.println(stringarr[i]);
}
Serial.println("------");
delay(5000);
}
//ALib Begin//
char** cSplit(char *string, char spliter, int* arrayCount)
{
//分割后字符串数量
int num = 0;
//计算数量
int i = 0;
int size = strlen(string);
for (; i < size; i++) {
if ((string[i] != spliter) && (string[i + 1] == spliter || string[i + 1] == '\0'))
num++;
}
*arrayCount = num;
//分配空间
char **cStrings = (char**)malloc(sizeof(char*) * (num + 1));
int j = 0;
for (; j <= num; j++){
//初始化指针数组
cStrings[j] = 0;
}
//保存分割后字符串
char *buffer = (char*)malloc(sizeof(char) * (size + 1));
int l = 0;
for (; l < size + 1; l++){
buffer[l] = 0;
}
int counter = 0;
int k = 0;
for (; k < size; k++){
if (string[k] != spliter){
int i = 0;
int j = k;
while (string[j] != spliter && string[j] != '\0') buffer[i++] = string[j++];
buffer[i] = '\0';
cStrings[counter] = (char*)malloc(sizeof(char) * i);
strcpy(cStrings[counter++], buffer);
k = k + i;
}
}
free(buffer);
return cStrings;
}
/**
*调用此方法释放cSplit分配的内存空间
*/
void freeStringsMemory(char **strings){
int k = 0;
for (; ; k++){
if (strings[k] != 0) free(strings[k]);
else break;
}
free(strings);
}
//ALib End//
评论加载中……

Recent

菜单加载中……
Index