У меня проблема с разделением содержимого строки, переданной функции. Функция вызывается с такой строкой:
ADD:Nathaniel:50
Где ADD будет именем протокола, Натаниэль будет ключом, а 50 будет значением, все разделены знаком :
.
Мой код выглядит так:
bool add_to_list(char* buffer){
char key[40];
char value[40];
int* token;
char buffer_copy[1024];
const char delim[2] = ":";
strcpy(buffer_copy, buffer);
token = strtok(NULL, delim);
//strcpy(key, token);
printf("%d",token);
printf("%p",token);
while(token != NULL){
token = strtok (NULL, delim);
}
//strcpy(value, token);
printf("%s", key);
printf("%s", value);
push(key, value);
return true;
}
Я пытаюсь сохранить каждый ключ и значение в отдельной переменной, используя strtok()
. Обратите внимание, что я пытаюсь сохранить второе и третье значения (Nathaniel
и 50
), а не первый бит (ADD
).
Когда я запускаю код, у меня возникает ошибка сегментации, поэтому я предполагаю, что пытаюсь получить доступ к недопустимому адресу памяти, а не к значению. Мне просто нужно сохранить второй и третий бит строки. Кто-нибудь может помочь, пожалуйста?
РЕДАКТИРОВАТЬ: я изменил код, чтобы он выглядел так:
bool add_to_list(char* buffer){
char *key, *value, *token;
const char *delim = ":";
token = strtok(buffer, delim);
//printf("%d",token);
printf("%s",token);
key = strtok(NULL, delim);
value = strtok(NULL, delim);
printf("%s", key);
printf("%s", value);
//push(key, value);
return true;
}
Но я все еще получаю ту же ошибку сегментации (сброшено ядро)
2 ответа
Первый вызов strtok()
должен предоставить строку для сканирования. Вы используете NULL
только для повторных вызовов, поэтому он продолжит обработку остальной части строки. ТАК первый вызов должен быть:
token = strtok(buffer_copy, delim);
Затем, когда вы хотите получить ключ и значение, вам нужно скопировать их в массивы:
token = strtok(NULL, delim);
key = strcpy(token);
token = strtok(NULL, delim);
value = strcpy(token);
Вам не нужен цикл, так как вы просто хотите извлечь эти два значения.
На самом деле, вам не нужно объявлять key
и value
как массивы, вы можете использовать указатели:
char *key, *value;
Тогда вы сможете:
token = strtok(buffer_copy, delim);
key = strtok(NULL, delim);
value = strtok(NULL, delim);
token
должно быть char*
, а не int*
.
Ваша основная проблема заключается в том, что при первом вызове strtok
первым параметром должна быть строка, которую вы хотите проанализировать, а не:
strcpy(buffer_copy, buffer);
token = strtok(NULL, delim);
Но
strcpy(buffer_copy, buffer);
token = strtok(buffer_copy, delim);
Кроме того, когда вы обнаруживаете токены в цикле while
, вы их выбрасываете. В этот момент вы хотите что-то сделать (или просто развернуть цикл и трижды вызвать strtok
).
Также:
const char* delim = ":";
Было бы более традиционным способом гарантировать завершение строки NUL
, чем:
const char delim[2] = ":";
Также рассмотрите возможность использования strtok_r
not strtok
, поскольку strtok
не является потокобезопасным и ужасным. Хотя вы здесь не используете потоки (кажется), вы также можете попрактиковаться.
strtok_r
, справочная страница - полезный ресурс, но вот что вам следует сделать. Для каждой токенизации строки, которую вы хотите выполнить (например, один раз в приведенном здесь примере), добавьте char *save=NULL;
перед первым использованием (технически инициализация не является обязательной), затем добавьте &save
в качестве дополнительного параметра при каждом использовании strtok
в этой токенизации и измените strtok
на strtok_r
. Это означает, что strtok_r
будет сохранять свое состояние между вызовами в save
, а не во внутреннем статическом буфере, поэтому у вас есть потокобезопасность.
Похожие вопросы
Новые вопросы
c
C - это язык программирования общего назначения, используемый для системного программирования (ОС и встраиваемых), библиотек, игр и кроссплатформенности. Этот тег следует использовать с общими вопросами, касающимися языка C, как это определено в стандарте ISO 9899 (последняя версия 9899: 2018, если не указано иное, а также для запросов, специфичных для версии, с c89, c99, c11 и т. Д.). C отличается от C ++ и не должен сочетаться с тэгом C ++ без разумной причины.
key
илиvalue
.int* token;
->char *token;
const char[2] delim
->const char* delim
strsep
вместо ужасногоstrtok
.