C语言 使用 strsep 解析 C 中的字符串(替代方法)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21383082/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Parsing a string in C with strsep (alternative methods)
提问by Kyrol
I want to parse a string, and I use strsepfunction:
我想解析一个字符串,我使用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 * rdoes 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 valgrind --tool=memcheck --leak-check=full --show-reachable=yes ./a.out
回答by Fred Foo
strsepoverwrites the target of its first (pointer-to-pointer) argument, so you lose the pointer to the malloc'd buffer's base. In fact, if you were do put a printf("%p\n", r);just before the free, you'd find out that you're freeing a null pointer, which has no effect.
strsep覆盖其第一个(指针到指针)参数的目标,因此您丢失了指向malloc'd 缓冲区基址的指针。事实上,如果您确实printf("%p\n", r);在 之前放置了free,您会发现您正在释放一个空指针,这没有任何效果。
The easy solution is to introduce an additional variable to keep that pointer around and freeit when you're done. Idiomatic usage would be
简单的解决方案是引入一个额外的变量来保持该指针,并free在您完成时保留它。惯用的用法是
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);
回答by jrk
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 endvariable and returns current value (into tokvariable).
它给出了相同的结果。但值得一提的是,strsep(3)将分隔符后的下一个值存储到end变量中并返回当前值(到tok变量中)。
回答by Wojtek Surowka
The strsep function updates its first argument (so it points right after the token it found). You need to store the value returned by malloc in a separate variable and free this variable.
strsep 函数更新它的第一个参数(因此它指向它找到的标记之后)。您需要将 malloc 返回的值存储在一个单独的变量中并释放该变量。

![C语言 将 argv[1] 存储到 char 变量](/res/img/loading.gif)