strtok_s завершает работу программы, когда строка имеет символ *

#c #arrays #string #pointers #strtok

#c #массивы #строка #указатели #strtok

Вопрос:

Я пытаюсь получить токен из строки, разделенной пробелом (» «). Но следующий код завершает работу приложения, когда строка имеет тип char *.

 #include <stdio.h>
#include <string.h>

int main(){

char *str1 = "Hello World!"; //char str1[] works
char *token;
char *savePtr;

token = strtok_s(str1, " ", amp;savePtr);

printf("%s", token);

return 0;
}
 

Я также получаю следующие предупреждения:

 C:UsersHarisDesktopC files>gcc firstProgram.c -o firstprogram.exe
firstProgram.c: In function 'main':
firstProgram.c:10:9: warning: implicit declaration of function 'strtok_s' [-Wimplicit-function-declaration]
 token = strtok_s(str1, " ", amp;savePtr);
         ^
firstProgram.c:10:7: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
 token = strtok_s(str1, " ", amp;savePtr);
 

Ответ №1:

strtok_s Функция изменяет объект, на который указывает указатель, превращая разделители в нули. Поэтому он не может принимать указатель на константу. Но вы передаете ее str1 , которая является указателем на строковую константу. Когда он пытается изменить эту строку, чтобы превратить разделители в нули, он пытается изменить константу. Это, конечно, незаконно.

Комментарии:

1. Спасибо. Но тогда как я могу использовать strtok_s для изменения строки? Какой тип должна иметь строка?

2. * измените строку и получите токен. Например, строка, с которой я работаю, — это «echo par par». Как я могу использовать эту функцию для получения «echo»?

3. Просто не передавайте ей указатель на константу. Вы можете сделать это char str1[]="hello world"; или подобное этому char *ptr=strdup("hello world"); или char buf[80]; strcpy(buf, "hello world"); — что угодно. Просто не передавайте ей указатель на константу.

4. Спасибо. Теперь это имеет смысл.

5. Просто любопытно, почему указатель на дубликат строки из strdup может быть изменен, но не исходный указатель?