使用指向字符的指针作为 strtok 的参数
Using pointer to character as the argument of strtok
我尝试使用 strtok
函数拆分字符串。但是如果我使用指向字符的指针作为这个函数的参数,程序就会失败。
如果我将字符串初始化为 s2
或 s3
,程序运行良好。但是如果我使用指向字符的指针作为 s1
程序得到 Segmentation fault (core dumped)
.
char *s1 = "1A 2B 3C 4D";
char s2[] = "1A 2B 3C 4D";
char s3[20] = "1A 2B 3C 4D";
问题出在其他函数上,printf
和 strlen
工作正常,但只有 strtok
出错。
完整代码如下:
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
void split_string(char *s) {
char * token = strtok(s," ");
while (token != NULL) {
printf("%s\n", token);
token = strtok(NULL, " ");
}
}
int main()
{
char *s1 = "1A 2B 3C 4D";
char s2[] = "1A 2B 3C 4D";
char s3[20] = "1A 2B 3C 4D";
printf("size of s1 = %ld, s2 = %ld, s3 = %ld\n", strlen(s1), strlen(s2), strlen(s3));
printf("s1: %s\ns2: %s\ns3: %s\n",s1,s2,s3);
printf("split s2: \n");
split_string(s2);
printf("split s3: \n");
split_string(s3);
printf("split s1: \n");
split_string(s1);
return 0;
}
运行后的结果:
size of s1 = 11, s2 = 11, s3 = 11
s1: 1A 2B 3C 4D
s2: 1A 2B 3C 4D
s3: 1A 2B 3C 4D
split s2:
1A
2B
3C
4D
split s3:
1A
2B
3C
4D
split s1:
Segmentation fault (core dumped)
strtok
来自 man
页:char *strtok(char *str, const char *delim);
请帮助理解这个问题。
strtok
修改给它的数据,字符文字是只读的。它会导致问题,在这种情况下是段错误。
其他表单将导致制作只读数据的副本,以便它们正常工作。
s1
指向一个字符串文字,它是常量,尝试修改字符串文字将导致段错误。
Battousai,首先你需要使用武士刀的反面,利用readable/writable区域来达到你的目的。如果你不这样做,除非compiler/OS(神谷薰)不阻止你,
Shishio Makoto 可能会通过 Sojiro Seta 毁掉对你和你身边重要的人,如 Sanosuke Sagara, 明神弥彦.
strtok
writes into the string you give it - overwriting the
separator character with null and keeping a pointer to the rest of the
string.
char *s1 = "1A 2B 3C 4D"; // you have a pointer to some read-only characters
char s2[] = "1A 2B 3C 4D"; // same, decay into pointer
char s3[20] = "1A 2B 3C 4D"; // a twenty element array of characters that you can do what you like with.
问题是 strtok()
修改了它的参数指向的字符串 - (它不仅仅解析它)并且通过给 s1
作为参数你试图修改字符串文字。
你的情况:
char s2[] = "1A 2B 3C 4D";
char s3[20] = "1A 2B 3C 4D";
s2
和 s3
都是可修改的 char
数组,每个数组都包含一个字符串,而:
char *s1 = "1A 2B 3C 4D";
s1
是指向字符串文字 "1A 2B 3C 4D"
的指针,它是只读的,不能修改。
任何修改字符串文字的尝试都会导致未定义的行为,在您的情况下会导致内存中的分段错误。
来自 ISO:IEC 9899:2018 (C18) 第 6.4.5/7 节 - "String literals":
"It is unspecified whether these arrays are distinct provided their
elements have the appropriate values. If the program attempts to
modify such an array, the behavior is undefined."
我尝试使用 strtok
函数拆分字符串。但是如果我使用指向字符的指针作为这个函数的参数,程序就会失败。
如果我将字符串初始化为 s2
或 s3
,程序运行良好。但是如果我使用指向字符的指针作为 s1
程序得到 Segmentation fault (core dumped)
.
char *s1 = "1A 2B 3C 4D";
char s2[] = "1A 2B 3C 4D";
char s3[20] = "1A 2B 3C 4D";
问题出在其他函数上,printf
和 strlen
工作正常,但只有 strtok
出错。
完整代码如下:
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
void split_string(char *s) {
char * token = strtok(s," ");
while (token != NULL) {
printf("%s\n", token);
token = strtok(NULL, " ");
}
}
int main()
{
char *s1 = "1A 2B 3C 4D";
char s2[] = "1A 2B 3C 4D";
char s3[20] = "1A 2B 3C 4D";
printf("size of s1 = %ld, s2 = %ld, s3 = %ld\n", strlen(s1), strlen(s2), strlen(s3));
printf("s1: %s\ns2: %s\ns3: %s\n",s1,s2,s3);
printf("split s2: \n");
split_string(s2);
printf("split s3: \n");
split_string(s3);
printf("split s1: \n");
split_string(s1);
return 0;
}
运行后的结果:
size of s1 = 11, s2 = 11, s3 = 11
s1: 1A 2B 3C 4D
s2: 1A 2B 3C 4D
s3: 1A 2B 3C 4D
split s2:
1A
2B
3C
4D
split s3:
1A
2B
3C
4D
split s1:
Segmentation fault (core dumped)
strtok
来自 man
页:char *strtok(char *str, const char *delim);
请帮助理解这个问题。
strtok
修改给它的数据,字符文字是只读的。它会导致问题,在这种情况下是段错误。
其他表单将导致制作只读数据的副本,以便它们正常工作。
s1
指向一个字符串文字,它是常量,尝试修改字符串文字将导致段错误。
Battousai,首先你需要使用武士刀的反面,利用readable/writable区域来达到你的目的。如果你不这样做,除非compiler/OS(神谷薰)不阻止你, Shishio Makoto 可能会通过 Sojiro Seta 毁掉对你和你身边重要的人,如 Sanosuke Sagara, 明神弥彦.
strtok
writes into the string you give it - overwriting the separator character with null and keeping a pointer to the rest of the string.
char *s1 = "1A 2B 3C 4D"; // you have a pointer to some read-only characters
char s2[] = "1A 2B 3C 4D"; // same, decay into pointer
char s3[20] = "1A 2B 3C 4D"; // a twenty element array of characters that you can do what you like with.
问题是 strtok()
修改了它的参数指向的字符串 - (它不仅仅解析它)并且通过给 s1
作为参数你试图修改字符串文字。
你的情况:
char s2[] = "1A 2B 3C 4D";
char s3[20] = "1A 2B 3C 4D";
s2
和 s3
都是可修改的 char
数组,每个数组都包含一个字符串,而:
char *s1 = "1A 2B 3C 4D";
s1
是指向字符串文字 "1A 2B 3C 4D"
的指针,它是只读的,不能修改。
任何修改字符串文字的尝试都会导致未定义的行为,在您的情况下会导致内存中的分段错误。
来自 ISO:IEC 9899:2018 (C18) 第 6.4.5/7 节 - "String literals":
"It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined."