Я не могу использовать strtok над символом - PullRequest
1 голос
/ 26 сентября 2019

Я не могу использовать strtok над char * a, но на b он работает.

Он работает с malloc и массивом

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DELIM ":"

int main()
{
    char *a = "xgdgsf: duh d";//unable to use strtok on it
    char *token=NULL;
    printf("%s",a);
    char *b = malloc(strlen(a) + 1);
    strcpy(b, a);//i can use strtko on it

    token=strtok(b,DELIM);
    printf("\n%s",token);
    token=strtok(a,DELIM);
    printf("\n%s",token);
    return 0;                                                                                        
 }

Ответы [ 3 ]

2 голосов
/ 26 сентября 2019

Вы передали a в strtok, который является строковым литералом.Вы не можете сделать это, потому что strtok изменяет строку.

Если бы вы определили массив как

const char *a = "xgdgsf: duh d";

, то компилятор выдаст вам предупреждение.

второй вызов strtok должен быть

token=strtok(NULL, DELIM);

для извлечения второго токена из b.

2 голосов
/ 26 сентября 2019

Изменить

char *a = "xgdgsf: duh d";

на

char *a = strdup("xgdgsf: duh d");

В C строковые литералы только для чтения.Однако помните, что вам нужно free указатель после вызова strdup.Сделайте это с free(a), когда закончите со строкой.

1 голос
/ 26 сентября 2019

Как уже отмечали другие, проблема в том, что a указывает на строковый литерал .strtok изменяет свой ввод (он перезаписывает разделители строковым терминатором), и при попытке изменить строковый литерал поведение undefined - вы можете получить ошибку во время выполнения, код может работать как ожидалось, иличто-то еще может случиться.Строковые литералы предполагаются неизменяемыми, но не гарантируется, что они будут храниться в постоянной памяти.

Есть несколько способов решить эту проблему.Один - объявить a как массив и инициализировать его строкой:

char a[] = "xgdgsf: duh d";

Другой - динамически выделить буфер и скопировать в него содержимое строки:

char *a = malloc( strlen( "xgdgsf: duh d" ) + 1 );
if ( a )
  strcpy( a, "xgdgsf: duh d" );

Если она доступна в вашей системе, вы можете использовать нестандартную функцию strdup, чтобы сделать то же самое:

char *a = strdup( "xgdgsf: duh d" );

При объявлении указателя на строковый литерал обычно хорошей идеей являетсяквалифицируйте его как const:

const char *a = "xgdgsf: duh d";

, таким образом компилятор будет вам мешать, если вы попытаетесь изменить (назначить) *a или a[i] или передать его функции, ожидающей простогоchar * в качестве ввода.Таким образом, ошибки, такие как использование strtok для литерала, обнаруживаются во время компиляции, а не во время выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...