是的,我也是新手。而且我已经有这个问题很长一段时间了。我试图用strtok来分割一个字符串,但问题是它不起作用。我已经看过人工页面和网上的例子,但我仍然没有答案。
在下面的代码中,我尝试使用在此站点中作为答案给出的示例代码。原来的while循环是:
char str[] = "hello world how are you?\n";
char *res;
res = strtok(str, " \n");
puts(res);
while (res != NULL)
{
res = strtok(NULL, " \n");
if(res!=NULL)
puts(res);
}
但是当将str更改为数据及其各自的分隔符(& =)时,它将变为分段错误。我该如何解决?代码中有什么问题?这是完整的代码。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char *data;
data = "integer1=1&integer2=2&integer3=3&integer4=4";
puts(data);
char str[] = "hello world how are you?\n";
char *res;
res = strtok(data, "=&");
puts(res);
while (res != NULL)
{
res = strtok(NULL, "=&");
if(res!=NULL)
puts(res);
}
return 0;
}
顺便说一句,strtok_r函数也不起作用。
答案 0 :(得分:3)
此:
char str[] = "hello world how are you?\n";
创建一个数组并使用字符串文字的内容对其进行初始化。但是,这个:
char *data;
data = "integer1=1&integer2=2&integer3=3&integer4=4";
声明data
是指向字符串文字的第一个字符的指针,当然,它是只读的,所以当strtok()
尝试修改它时,它会失败(调用未定义的行为) )。
注意:
这就是为什么你将指向字符串文字的指针声明为const char *
而 明确地不是 char *
,如果这样做的话,我会找到你并使你符合资格。
Arrays are not pointers, they never were, and they never will be either.
答案 1 :(得分:2)
您正在观察的行为可以通过com.lang.c FAQ中的问题1.32解释:
这些初始化之间有什么区别?
char a[] = "string literal"; char *p = "string literal";
如果我尝试为p [i]指定新值,我的程序会崩溃。
答案是:
字符串文字(C源中双引号字符串的正式术语)可以两种略有不同的方式使用:
- 作为char数组的初始值设定项,如char a []的声明,它指定该数组中字符的初始值(如果需要,还指定其大小)。
- 在其他地方,它变成一个未命名的静态字符数组,这个未命名的数组可能存储在只读存储器中,因此不一定能被修改。在表达式上下文中,像往常一样将数组一次转换为指针(参见第6节),因此第二个声明将p初始化为指向未命名数组的第一个元素。
醇>
答案 2 :(得分:0)
strtok
打破内存块。文字字符串不能修改。因此,您不能同时使用strtoke
。
试试这个:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(){
char *data;
data = "integer1=1&integer2=2&integer3=3&integer4=4";
char *cur, *res;
cur = data;
res = strpbrk(cur, "=&");
while (res != NULL)
{
fwrite(cur, 1, res-cur, stdout);
fputc('\n', stdout);
cur = res + 1;
res = strpbrk(cur, "=&");
}
fputs(cur, stdout);
return 0;
}
这不会修改内存块。