Using pointer to character as the argument of strtok

僤鯓⒐⒋嵵緔 提交于 2021-02-08 05:28:15

问题


I try to split the string by using strtok function. But the program become failed if i use the pointer to character as the argument of this function.

If i initialize the string as s2 or s3 the program works well. But if i use pointer to character as s1 the program get Segmentation fault (core dumped).

char *s1 = "1A 2B 3C 4D";
char s2[] = "1A 2B 3C 4D";
char s3[20] = "1A 2B 3C 4D";

The problem is the other functions, printf and strlen work without failure, but only strtok get error.

The complete code below:

#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;
}

The result after running:

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 from man page: char *strtok(char *str, const char *delim);

Please help to understand this problem.


回答1:


Battousai, firstly you need to use your reverse side of the katana to achieve your aim by using readable/writable area. If you don't do this, unless the compiler/OS(Kamiya Kaoru) doesn't prevent you, Shishio Makoto may ruin guys important for you and around you via Sojiro Seta, living in your memory such as Sanosuke Sagara, Yahiko Myojin.

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.



回答2:


strtok modifies the data given to it and character literals are read only. It will cause problems, in this case a segfault.

The other forms will cause a copy of the read only data to be made so they work correctly.




回答3:


s1 points to a string literal, which is constant, any attepmpt to modify a string literal will result in a segfault.




回答4:


The problem is that strtok() modifies the string pointed to by its argument - (it does not parse it only) and by giving s1 as argument you attempt to modify a string literal.


In your case:

char s2[] = "1A 2B 3C 4D";
char s3[20] = "1A 2B 3C 4D";

s2 and s3 are both modifiable char arrays which each hold a string, whereas:

char *s1 = "1A 2B 3C 4D";

s1 is a pointer to the string literal "1A 2B 3C 4D", which is read-only and can´t be modified.

Any attempt to modify a string literal causes undefined behavior and in your case the segmentation fault in memory.

From ISO:IEC 9899:2018 (C18) Section 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."



来源:https://stackoverflow.com/questions/61029394/using-pointer-to-character-as-the-argument-of-strtok

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!