[英]how to effectively use strtok function
Yes, I'm a newbie as well. 是的,我也是新手。 And I have been having this problem for quite some time. 我已经有很长时间了。 I'm trying to use strtok to split off a string, but the thing is it does not work. 我正在尝试使用strtok拆分字符串,但事实是它不起作用。 I have looked at the example on the man-pages as well as those online, and I still don't have the answer. 我已经看过手册页以及在线上的示例,但仍然没有答案。
In the code below, I tried to use the sample code given as an answer in this site. 在下面的代码中,我尝试使用此站点中给出的示例代码作为答案。 The original while loop is: 原始的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);
}
but when a change the str to data, and its respective delimiters (&=), it becomes a Segmentation Fault. 但是,如果将str更改为data及其相应的定界符(&=),则它将变为Segmentation Fault。 How do I fix this? 我该如何解决? What's wrong in the code? 代码有什么问题? Here is the complete code. 这是完整的代码。
#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;
}
by the way, the strtok_r function doesn't work either. 顺便说一句,strtok_r函数也不起作用。
This: 这个:
char str[] = "hello world how are you?\n";
creates an array and initializes it with the contents of the string literal. 创建一个数组,并使用字符串文字的内容对其进行初始化。 This, however: 但是,这是:
char *data;
data = "integer1=1&integer2=2&integer3=3&integer4=4";
declares data
to be a pointer to the first character of the string literal, which is, of course, read-only, so when strtok()
tries to modify it, it fails (invoking undefined behavior). 将data
声明为指向字符串文字的第一个字符的指针,该指针当然是只读的,因此当strtok()
尝试对其进行修改时,它将失败(调用未定义的行为)。
Notes: 笔记:
So that's why you declare pointers to string literals as const char *
and explicitly not as char *
, and if you do so, I will find you and const-qualify you. 因此,这就是为什么将指向字符串文字的指针声明为const char *
而不是声明为 char *
,如果这样做,我将找到您并const限定您的身份 。
Arrays are not pointers, they never were, and they never will be either. 数组不是指针,它们从来都不是指针,也永远不会是指针。
The behaviour you're observing can be explained by question 1.32 in com.lang.c FAQ : 您所观察到的行为可以通过com.lang.c FAQ中的问题1.32来解释:
What is the difference between these initializations? 这些初始化之间有什么区别?
char a[] = "string literal"; char *p = "string literal";
My program crashes if I try to assign a new value to p[i]. 如果尝试为p [i]分配新值,程序将崩溃。
And the answer is: 答案是:
A string literal (the formal term for a double-quoted string in C source) can be used in two slightly different ways: 字符串文字(C源代码中双引号字符串的正式术语)可以以两种略有不同的方式使用:
- As the initializer for an array of char, as in the declaration of char a[] , it specifies the initial values of the characters in that array (and, if necessary, its size). 作为char数组的初始化程序,如在char a []的声明中一样,它指定该数组中字符的初始值(并在必要时指定其大小)。
- Anywhere else, it turns into an unnamed, static array of characters, and this unnamed array may be stored in read-only memory, and which therefore cannot necessarily be modified. 在其他任何地方,它都变成了一个未命名的静态字符数组,并且该未命名的数组可以存储在只读存储器中,因此不必进行修改。 In an expression context, the array is converted at once to a pointer, as usual (see section 6), so the second declaration initializes p to point to the unnamed array's first element. 在表达式上下文中,通常将数组立即转换为指针(请参见第6节),因此第二个声明将p初始化为指向未命名数组的第一个元素。
strtok
break memory block. strtok
中断存储块。 And literal strings can't modofiy. 文字字符串不能模化。 So you can't use strtoke
for both. 因此,您不能同时使用strtoke
。 Try this: 尝试这个:
#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;
}
This doesn't modify memory block. 这不会修改内存块。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.