用定界符分割字符串数组

问题描述

我正在使用以下代码拆分char数组:

    char* Split(char* e,int index) {
  index = index -1;
  char* v[index +2];
  char *p;
  int i = 0;
  p = strtok(e,",");
  while(p && i < index +2)
   {
    v[i] = p;
    p = strtok(NULL,");
    i++;
  };
//  Serial.println(v[0]);
  //Serial.println(v[1]);
 // Serial.println(v[2]);
  return v[index];
 };

我正在这调用函数

 char array[]="1,3,4,55,6,7,66";
 Serial.println("array:");
Serial.println(array);
 char *out;
 out = Split(array,2);
 Serial.println("out:");
 Serial.println(out);
 Serial.println("array:");
 Serial.println(array);
 out = Split(array,2);
 Serial.println("out:");
 Serial.println(out);

我第一次调用函数时,一切都很好。我得到的结果是“ 3”,这就是我所期望的。

但是第二次调用函数,事情就变得疯狂了,我得到了一些象形文字

当我用Serial输出检查变量时,我看到“ array”是第二次才是“ 1”,这可能是函数输出奇怪的原因。

但是我不明白该函数的第一次调用如何影响“数组”的值,因为该变量在函数中没有被触及。 有人可以帮助我澄清这个问题吗?

串行接口的输出如下:

array:
1,66
out:
3
array:
1
out:
⸮}⸮a⸮⸮-:⸮⸮⸮m⸮⸮⸮⸮⸮⸮⸮]⸮ʻ⸮T⸮;⸮⸮⸮N}⸮⸮⸮⸮{R⸮U)⸮⸮⸮[G⸮⸮`j⸮⸮⸮⸮⸮v⸮⸮wz⸮⸮s⸮⸮⸮⸮⸮⸮}⸮⸮2⸮⸮vz~⸮⸮⸮⸮O}⸮⸮⸮/⸮⸮nv⸮⸮^j⸮yO⸮7{⸮⸮⸮⸮z⸮Z⸮⸮⸮⸮⸮⸮⸮7[⸮⸮⸮j⸮w⸮⸮⸮⸮⸮⸮⸮w)⸮⸮c⸮⸮}⸮⸮⸮⸮⸮⸮⸮⸮⸮v⸮⸮׺⸮m/V⸮ys<⸮⸮ٿ⸮⸮⸮׆⸮+>ֻ⸮z6⸮=⸮D⸮⸮⸮⸮~⸮⸮⸮⸮e⸮⸮?⸮=⸮⸮W⸮⸮⸮⸮}⸮e⸮ߣN绮⸮w⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮w⸮⸮⸮⸮?⸮⸮⸮⸮⸮⸮⸮Y⸮⸮޴f⸮v⸮⸮u⸮p?⸮⸮^h⸮⸮}⸮⸮ݼ⸮^Wo⸮⸮⸮⸮⸮_⸮⸮⸮⸮⸮⸮;s⸮⸮⸮⸮wZ⸮⸮⸮~⸮7⸮⸮⸮r⸮⸮⸮⸮)⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮f⸮⸮O⸮⸮⸮⸮⸮⸮⸮⸮⸮
⸮⸮7⸮⸮a.⸮⸮.kG⸮⸮8⸮⸮⸮⸮⸮⸮⸮⸮U⸮⸮⸮⸮⸮⸮⸮⸮⸮'⸮we⸮⸮⸮M⸮{⸮⸮Lu⸮no⸮⸮⸮>⸮⸮⸮⸮⸮⸮⸮~}⸮⸮⸮⸮⸮⸮⸮⸮y⸮⸮o⸮⸮⸮,'>}⸮⸮⸮+⸮X⸮⸮⸮/⸮⸮ױ⸮⸮⸮⸮̲⸮⸮-_M⸮⸮⸮⸮L~⸮#Φz~⸮⸮⸮⸮?⸮⸮⸮⸮⸮{/⸮_⸮:⸮jmc⸮m]S⸮_3⸮>o⸮׷⸮ݸv⸮⸮⸮|⸮
⸮⸮{_^⸮⸮o⸮?⸮⸮⸮⸮⸮⸮_⸮⸮⸮⸮{⸮⸮⸮^⸮⸮⸮⸮⸮⸮⸮⸮⸮ퟺ⸮⸮߿⸮⸮p⸮⸮⸮w?=⸮⸮⸮X⸮⸮⸮⸮⸮⸮_⸮oy⸮⸮M⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮w⸮⸮⸮[⸮⸮o⸮⸮⸮⸮޿7wE~⸮⸮⸮⸮⸮N⸮⸮o⸮x⸮=v/⸮⸮⸮⸮>⸮9⸮⸮ί⸮Y_Q⸮⸮l⸮⸮}'⸮⸮}⸮?⸮⸮ޭ⸮6⸮7⸮{⸮T⸮⸮⸮ ⸮r⸮⸮⸮⸮⸮⸮⸮
ܽ+'⸮⸮⸮⸮G⸮f⸮z⸮Gn⸮⸮n⸮/⸮⸮⸮⸮/⸮⸮⸮⸮Q⸮⸮⸮⸮⸮o⸮;⸮L⸮⸮r⸮⸮⸮⸮n/߿ſ⸮⸮⸮⸮q⸮⸮⸮ݮ⸮⸮⸮⸮⸮⸮+⸮⸮⸮⸮⸮⸮ﷹln?⸮⸮⸮⸮q⸮⸮⸮{⸮⸮⸮⸮⸮⸮⸮q⸮-⸮⸮{(⸮⸮f⸮⸮{⸮v⸮܀⸮oq⸮⸮⸮⸮⸮⸮߽⸮⸮nj⸮⸮⸮os⸮6۟g⸮⸮⸮⸮"⸮⸮7Z7⸮⸮yo⸮ӟ⸮⸮⸮w⸮⸮⸮⸮⸮⸮{⸮⸮⸮Vr⸮⸮]_⸮׷SS⸮_⸮w⸮⸮⸮wl⸮⸮⸮⸮P⸮⸮z⸮⸮m{⸮⸮⸮ݛs⸮(⸮⸮r⸮⸮˷:⸮%⸮⸮⸮⸮Z⸮⸮⸮m⸮W⸮⸮⸮⸮ם*⸮⸮⸮[>⸮⸮⸮/⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮?⸮⸮⸮⸮|⸮.⸮⸮⸮{⸮⸮⸮ꍥ⸮⸮⸮|⸮⸮⸮⸮⸮⸮⸮⸮⸮7~Ls⸮!⸮⸮⸮⸮⸮{⸮x⸮g⸮⸮|֍om~~⸮⸮⸮{⸮cϠ⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮>;⸮W⸮⸮⸮⸮⸮⸮⸮⸮q⸮⸮[:⸮'⸮#⸮o⸮⸮_⸮uϾ⸮⸮⸮⸮[⸮⸮^⸮⸮⸮n⸮}⸮⸮⸮⸮⸮>/⸮_⸮⸮-⸮⸮⸮⸮s⸮⸮⸮}⸮⸮⸮⸮/⸮[w⸮⸮r⸮⸮_⸮⸮⸮⸮,⸮⸮ݯ⸮⸮⸮7ÿ⸮:⸮⸮⸮⸮Ί⸮⸮⸮⸮⸮t[|⸮⸮w⸮F⸮⸮⸮

解决方法

好的,我通过使数组与strtok的更改无关地实现了

void setup(){
  Serial.begin(115200);
  char array[]="1,3,4,55,6,7,66";

 char *out;
 char array2[8];
 strcpy(array2,array);
  Serial.println("array2:");
Serial.println(array2);
 out = Split(array2,2);
 Serial.println("out:");
 Serial.println(out);
 Serial.println("array3:");
  char array3[8];
 strcpy(array3,array);
 Serial.println(array3);
 out = Split(array3,2);
 Serial.println("out:");
 Serial.println(out);
}

不是那么优雅,但是可以用!!

有人有更好的主意吗?

,

有人有更好的主意吗?

该解决方案取决于您的数据,如果您的数据始终像是一个用,分隔的整数列表的字符串,那么最好将其拆分为int数组,然后编写通用的split()函数。

#define NUMBER_OF_ELEMENT 7

int splitted[NUMBER_OF_ELEMENT];
const char* delimiter = ",";

void split(const char *str,const char *delimiter) {
  char temp[strlen(str)+1] = {0};
  memcpy(temp,str,strlen(str));

  int i=0;
  char *p = strtok(temp,delimiter);
  while(p != NULL) {
    splitted[i++] = atoi(p);
    p = strtok(NULL,delimiter);
  }
}

int setup() {
  char array[]="1,66";
  
  Serial.begin(115200);

  split(array,delimiter);

  // get every splitted element as an int
  for (int i=0; i<NUMBER_OF_ELEMENT,i++) {
    Serial.print("Out:");
    Serial.println(splitted[i]);
  }

  //if you really want to have string as result
  Serial.println(String(splitted[3]));
}
,

谢谢,太好了! 是的,我的数据总是int。因此,您的功能对我来说很完美。 但是为了结构清晰,我宁愿使用返回值,而不是更改全局变量“ splitted”。 这是一个好习惯吗?还是您更喜欢使用变体来节省RAM?

,

这是我完成此任务的最终解决方案。该函数仅根据给定的索引返回一个值:

int splitStrToInt(char *str,int index) {
    //******************
    //This function splits a string that is separated by commas and converts the values ​​to int,//according to the given index
    //caution!! The string may only consist of numerical values ​​!!
    //Example: "1,66"
    //******************
    index--;
    char e[strlen(str) + 1] = { 0 }; 
    memcpy(e,strlen(str));
    int v[index + 2];
    char *p;
    int i = 0;
    p = strtok(e,",");
    while (p && i < index + 2) {
        v[i] = atoi(p);            
        p = strtok(NULL,");
        i++;
    }
    ;

    return v[index];
}