解析带有多字符分隔符的字符串,并在c中的第二次调用中得到垃圾数据和结果

时间:2013-03-14 05:35:32

标签: c string split malloc buffer

我编写了一个代码,用多个字符分隔符拆分字符串。

第一次调用此函数时工作正常

但我第二次调用它时会用一些不需要的符号重新调整正确的单词。

我认为这个问题是因为没有清除缓冲区而发生的。我已经尝试了很多但是无法解决这个问题。请帮我解决这个问题。

char **split(char *phrase, char *delimiter) {
    int i = 0;
    char **arraylist= malloc(10 *sizeof(char *));
    char *loc1=NULL;
    char *loc=NULL;
    loc1 = phrase;
    while (loc1 != NULL) {
    loc = strstr(loc1, delimiter);
    if (loc == NULL) {
            arraylist[i]=malloc(sizeof(loc1));
            arraylist[i]=loc1;
            break;
    }
    char *buf = malloc(sizeof(char) * 256);    // memory for 256 char
    int length = strlen(delimiter);
    strncpy(buf, loc1, loc-loc1);
    arraylist[i]=malloc(sizeof(buf));
    arraylist[i]=buf;
    i++;
    loc = loc+length;
    loc1 = loc;
}
return arraylist;
}

第一次调用此函数

char **splitdetails = split("100000000<delimit>0<delimit>hellooo" , "<delimit>");

它给出了

splitdetails[0]=100000000
splitdetails[1]=0
splitdetails[2]=hellooo

但我第二次打电话

char **splitdetails = split("20000000<delimit>10<delimit>testing" , "<delimit>");

splitdetails[0]=20000000��������������������������
splitdetails[1]=10����
splitdetails[2]=testing

更新: -

感谢@fatelerror。我已将我的代码更改为

    char** split(char *phrase, char *delimiter) {
    int i = 0;
    char **arraylist = malloc(10 *sizeof(char *));
    char *loc1=NULL;
    char *loc=NULL;
    loc1 = phrase;
    while (loc1 != NULL) {
    loc = strstr(loc1, delimiter);
    if (loc == NULL) {
            arraylist[i]=malloc(strlen(loc1) + 1);
            strcpy(arraylist[i], loc1);
            break;
    }
    char *buf = malloc(sizeof(char) * 256);    // memory for 256 char
    int length = strlen(delimiter);
    strncpy(buf, loc1, loc-loc1);
    buf[loc - loc1] = '\0';
    arraylist[i]=malloc(strlen(buf));
    strcpy(arraylist[i], buf);
    i++;
    loc = loc+length;
    loc1 = loc;
   }
}  

在调用者函数中,我将其用作

char *id
char **splitdetails = split("20000000<delimit>10<delimit>testing" , "<delimit>");
id = splitdetails[0];
//some works done with id
//free the split details with this code.
for(int i=0;i<3;i++) {
    free(domaindetails[i]);
}free(domaindetails);
domaindetails=NULL;    

然后我打电话给第二个,

char **splitdetails1= split("10000000<delimit>1000<delimit>testing1" , "<delimit>");

它出错,我无法释放该功能。

提前感谢。

1 个答案:

答案 0 :(得分:3)

您的问题可归结为三个基本内容:

  1. sizeof不是strlen()
  2. 作业不会复制C中的字符串。
  3. strncpy()并不总是nul-terminate字符串。
  4. 所以,当你说出类似的话时:

    arraylist[i]=malloc(sizeof(loc1));
    arraylist[i]=loc1;
    

    这不会复制字符串。第一个分配loc1的大小,即char *。换句话说,您分配了指针的大小。您希望分配存储来存储字符串,即使用strlen()

    arraylist[i]=malloc(strlen(loc1) + 1);
    

    同样注意+ 1,因为你还需要空间用于nul-terminator。然后,复制要使用的字符串strcpy()

    strcpy(arraylist[i], loc1);
    

    你拥有它的方式只是指定一个指向旧字符串的指针(并且在处理过程中你刚刚分配的内存)。使用结合这两个步骤的strdup()也很常见,即

    arraylist[i] = strdup(loc1);
    

    这很方便,但strdup()不是官方C库的一部分。在考虑使用代码之前,需要评估代码的可移植性需求。

    此外,对于strncpy(),您应该知道始终是nul-terminate:

    strncpy(buf, loc1, loc-loc1);
    

    这比原始字符串中的字节数少,并且不会终止buf。因此,有必要自己包含一个nul终结符:

    buf[loc - loc1] = '\0';
    

    这是你看到垃圾的根本原因。由于你没有nul终止,C不知道你的字符串在哪里结束,所以它继续读取内存中发生的任何事情。