将char数组拆分为单独的字符串

时间:2015-07-13 06:51:43

标签: c

我的数据看起来像这样:

header:dataA:dataB

我正在尝试将标头和dataA和dataB作为单独的字符串。 所以我写了这个功能可能不太好:

#define maxDataSize 50
//.....

char header[20];
char dataA[maxDataSize];   
char dataB[maxDataSize]; 

//**** a call to the function that parse the data
getHeader(BLEcontent,1,header); // here "BLEcontent" has the incoming data
getHeader(BLEcontent,2,dataA);
getHeader(BLEcontent,3,dataB);

//***** call the function that use the data
newDataFromBLE(header,dataA, dataB);

//function that parses the data:
void getHeader( char localString[], int seperatorNum,char *newdata)
{   
    const char seperator=':';  
    int counter=0;
    int divider=0;

    //clear array when it has garbage it added
    for( int i = 0; i < maxDataSize;  ++i )
        newdata[i] = (char)0;

    for(int k=0;k<maxDataSize;k++)
    { 
        if ( localString[k]==  seperator   )
        {  
            counter++;
            divider=k+1;
            if(counter==seperatorNum)
            {   return ;     } 
        }
        if( (seperatorNum-1) ==counter)
            newdata[k-divider]=localString[k];
    }
    return ;   
}

稍后当我尝试使用函数数据时,存储在header / dataA / dataB中:

void newDataFromBLE(char header[],char dataA[], char dataB[])
{
    Serial.println("got:");
    Serial.println(header);
    Serial.println(dataA);
    Serial.println(dataB);
    if (strcmp (header,"setWifi") == 0)
        //... do stuff here

我在这里得到了一些非常奇怪的结果。例如,如果传入的数据是setWifi:a,我会得到一个好的结果。如果是abcd:abc我会得到垃圾。如果它是setWifi:a:b,我也会得到垃圾。

似乎如果我发送的内容与第一个if语句不对应,即使它在if之前也会给我垃圾。似乎它知道(??)关于即将到来的if ..

以前工作过..

2 个答案:

答案 0 :(得分:3)

要拆分数据,您可以使用char* strtok( char* str, const char* delim );功能。 对于线程安全,请使用char *strtok_r(char *str, const char *delim, char **saveptr);函数。

请参阅以下使用strtok_r函数的示例:

#include <stdio.h>
#include <string.h>

//#define maxsize 20
int main ()
{
  int i = 0;
  char str[] ="setWifi:dataA:dataB";
  char *delimeter = ":";
  char *saveptr1;
  char *header = strtok_r(str, delimeter, &saveptr1);
  char **dataArr = malloc(5);

  for (i=0; i< 5; i++) {
    dataArr[i] =  strtok_r(NULL, delimeter, &saveptr1);
    if (dataArr[i] == NULL)
        break;
    printf(" %s\n", dataArr[i]);
  }


  if (strcmp(header, "setWifi") == 0) {
    printf("'setWifi' header was set!");
  }
  free(dataArr);

  return 0;
}

工作示例: http://ideone.com/renn2q

输出:

 dataA
 dataB
'setWifi' header was set!
  

strtok_r()函数是一个可重入的版本strtok()。 saveptr   argument是指向内部使用的char *变量的指针   strtok_r()以便在连续调用之间维护上下文   解析相同的字符串。

请参阅:http://linux.die.net/man/3/strtok_r

答案 1 :(得分:1)

您可以使用strsepman page

  

引入strsep()函数作为strtok(3)的替代,因为后者无法处理空字段。它是线程安全的。

使用strsep

#include <string.h>
#include <stddef.h>

. . .

const char string[] = "header:dataA:dataB";
const char delimiters[] = ":";
char * running = strdupa(string);
char * token;

. . .

token = strsep(&running, delimiters);    /* token => "header" */
token = strsep(&running, delimiters);    /* token => "dataA" */
token = strsep(&running, delimiters);    /* token => "dataB" */
token = strsep(&running, delimiters);    /* token => NULL */