使用strtok_r时的分段错误
任何人都可以解释为什么我在以下示例中出现分段错误?使用strtok_r时的分段错误
#include <stdio.h>
#include <string.h>
int main(void) {
char *hello = "Hello World, Let me live.";
char *tokens[50];
strtok_r(hello, " ,", tokens);
int i = 0;
while(i < 5) {
printf("%s\n", tokens[i++]);
}
}
试试这个:
#include <stdio.h>
#include <string.h>
int main(void) {
char hello[] = "Hello World, Let me live."; // make this a char array not a pointer to literal.
char *rest; // to point to the rest of the string after token extraction.
char *token; // to point to the actual token returned.
char *ptr = hello; // make q point to start of hello.
// loop till strtok_r returns NULL.
while(token = strtok_r(ptr, " ,", &rest)) {
printf("%s\n", token); // print the token returned.
ptr = rest; // rest contains the left over part..assign it to ptr...and start tokenizing again.
}
}
/*
Output:
Hello
World
Let
me
live.
*/
我认为这可能是char *tokens[50];
因为你已经声明它是一个指针时,它已经是一个指针。一个数组已经是一个声明的指针。你的意思是说char tokens[50];
。这应该够了吧。
你对C的理解似乎比我弱...... – 2010-02-09 06:40:53
strtok_r尝试空字符写入你好(这是非法的,因为它是一个常量字符串)
我试过了'char hello [50]'。分段错误消失了,但现在问题在于'printf'只是打印可悲的空白行。 :( – 2010-02-09 06:39:31
您已经明白strtok_r的使用不正确。请检查该example和文档
并尝试&看到这一点:
#include <stdio.h>
#include <string.h>
int main(void)
{
char hello[] = "Hello World, let me live.";
char *tmp;
char *token = NULL;
for(token = strtok_r(hello, ", ", &tmp);
token != NULL;
token = strtok_r(NULL, ", ", &tmp))
{
printf("%s\n", token);
}
return 0;
}
一堆东西错了:
hello
指向字符串文字,必须将其视为不可变。 (它可以存在只读存储器中。)由于strtok_r
突变了其参数字符串,因此不能使用hello
。您只需拨打
strtok_r
一次,并且不要初始化tokens
阵列指向任何内容。
试试这个:
#include <stdio.h>
#include <string.h>
int main(void) {
char hello[] = "Hello World, Let me live.";
char *p = hello;
char *tokens[50];
int i = 0;
while (i < 50) {
tokens[i] = strtok_r(p, " ,", &p);
if (tokens[i] == NULL) {
break;
}
i++;
}
i = 0;
while (i < 5) {
printf("%s\n", tokens[i++]);
}
return 0;
}
感谢您的回答。我希望SO允许将多个答案标记为正确的。 :) – 2010-02-09 07:01:08
- 你需要调用
strtok_r
在一个循环。第一次给它字符串进行标记,然后你给它NULL
作为第一个参数。 -
strtok_r
以char **
作为第三个参数。tokens
是一个50char *
值的数组。当您将tokens
传递给strtok_r()
时,传递的值是指向该数组的第一个元素的char **
值。这没关系,但是你正在浪费49个根本不用的值。您应该有char *last;
并使用&last
作为strtok_r()
的第三个参数。 -
strtok_r()
修改它的第一个参数,所以你不能传递一些无法修改的东西。 C中的字符串文字是只读的,所以你需要一些可以修改的东西:例如char hello[] = "Hello World, Let me live.";
。
感谢您的答案。我希望SO允许将多个答案标记为正确的。 :) – 2010-02-09 07:00:31
+1,最佳答案。 – 2010-02-09 07:01:09
@Scrub:很高兴能有帮助。确保你明白了我的第二点(关于'char * tokens [50];'当传递给函数时'等同于'char **')。 – 2010-02-09 07:04:55
谢谢吨。:) – 2010-02-09 06:59:23
这个例子给我一个printf行的段错误。 gdb打印令牌显示0xffffffffffffdad0 当我编译proj1.c:33:2时警告:隐式声明函数'strtok_r'[-Wimplicit-function-declaration] proj1。c:33:14:warning:赋值使得整型指针没有强制转换[缺省情况下启用] – schwiz 2012-10-01 00:48:21
对不起,我是一个新手,为什么不应该是'char * ptr = Hello;'大写H?此外,Alok的回答说,第一次参数需要“标记”,然后后续调用需要为NULL,但是看起来你的例子只是把它称为while循环中的一种方式?感谢代码btw – 2012-12-17 22:48:16