简体   繁体   English

使用strsep在C中解析字符串(替代方法)

[英]Parsing a string in C with strsep (alternative methods)

I want to parse a string, and I use strsep function: 我想解析一个字符串,我使用strsep函数:

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

int main()
{

  char str[] = "Marco:Q:2F7PKC";
  char *token1, *token2, *token3;
  char *r = malloc(30);

  strcpy(r, str);

  token1 = strsep(&r, ":");
  token2 = strsep(&r, ":");
  token3 = strsep(&r, ":");

  printf("tok1 = %s\n", token1);
  printf("tok2 = %s\n", token2);
  printf("tok3 = %s\n", token3);

  free(r);

  return 0;

}

The function do its job well, but If I launch valgrind , the allocated string char * r does not freed correctly ( definitely lost: 30 bytes in 1 blocks ). 该函数完成了它的工作,但是如果我启动valgrind ,分配的字符串char * r没有正确释放( 肯定会丢失:1个块中的30个字节 )。

I'd like to know why and if there are alternative way to do the same thing, maybe without call strsep . 我想知道为什么以及是否有其他方法可以做同样的事情,也许没有呼叫strsep

I call valgrind with valgrind --tool=memcheck --leak-check=full --show-reachable=yes ./a.out 我用valgrind --tool=memcheck --leak-check=full --show-reachable=yes ./a.out调用valgrind valgrind --tool=memcheck --leak-check=full --show-reachable=yes ./a.out

strsep overwrites the target of its first (pointer-to-pointer) argument, so you lose the pointer to the malloc 'd buffer's base. strsep覆盖其第一(指针到指针)参数的目标,这样你就失去了指针malloc “d缓冲区的基础。 In fact, if you were do put a printf("%p\\n", r); 事实上,如果你确实放了一个printf("%p\\n", r); just before the free , you'd find out that you're freeing a null pointer, which has no effect. 就在free之前,你会发现你正在释放一个无效的空指针。

The easy solution is to introduce an additional variable to keep that pointer around and free it when you're done. 简单的解决方案是引入一个额外的变量来保持指针并在完成后free它。 Idiomatic usage would be 习惯用法是

char *r = strdup("Marco:Q:3F7PKC");
// check for errors

char *tok = r, *end = r;
while (tok != NULL) {
    strsep(&end, ":");
    puts(tok);
    tok = end;
}

free(r);

I would like to a bit simplify a good reply from Fred Foo: 我想稍微简化Fred Foo的回复:

char *end, *r, *tok;

r = end = strdup("Marco:Q:3F7PKC");
assert(end != NULL);

while ((tok = strsep(&end, ":")) != NULL) {
    printf("%s\n", tok);
}

free(r);

It gives the same result. 它给出了相同的结果。 But it is worth to say that strsep(3) stores next value after delimiter into end variable and returns current value (into tok variable). 但值得一提的是, strsep(3)将分隔符存储到end变量后存储下一个值并返回当前值(转换为tok变量)。

The strsep function updates its first argument (so it points right after the token it found). strsep函数更新其第一个参数(因此它指向它找到的标记之后)。 You need to store the value returned by malloc in a separate variable and free this variable. 您需要将malloc返回的值存储在单独的变量中并释放此变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM