Как мне использовать strtok, чтобы вырезать строку, которая различается по размеру? - PullRequest
0 голосов
/ 27 марта 2019

Итак, я довольно новичок в C, и я получаю в качестве ввода строку, подобную этой a:name:number:number:number:number:name:name, и я использую strtok, чтобы получить все имена и числа без ":". Дело в том, что размер строки может варьироваться, и он может иметь до двух имен (всегда в конце), таких как: a:name:number:number:number:number:name:name:name или a:name:number:number:number:number:name:name:name:name.

Теперь я использую struct и strcpy, чтобы получить каждое имя в структуре, но из-за количества изменений имен в конце я получаю ошибки сегментации, когда в конце меньше 4 имен, то есть максимальное количество имен (минимум 1), и я думаю, что это потому, что я продолжаю делать strtok после конца строки.

Вот мой код:

char *token;
structname a;
token = strtok(c,":"); //c is the input string
strcpy(a.name1,strtok(NULL,":"));
a.number1 = atoi(strtok(NULL,":"));
a.number2 = atoi(strtok(NULL,":"));
a.number3 = atoi(strtok(NULL,":"));
a.number4 = atoi(strtok(NULL,":"));
strcpy(a.name2,strtok(NULL,":"));
strcpy(a.name3,strtok(NULL,":"));
strcpy(a.name4,strtok(NULL,":"));
strcpy(a.name5,strtok(NULL,":"));

Итак, я предполагаю, что ошибка возникает из-за того, что она продолжает выполнять strtok даже после окончания строки в тех случаях, когда нет 4 отчеств? Я хочу знать, как я могу, например, в случае, когда в конце есть 2 имени, просто получите a.name4 и a.name5 до "\0" или просто не получите ничего в этих строках. Спасибо за время и помощь!

Ответы [ 2 ]

1 голос
/ 27 марта 2019

strotok () возвращает NULL, если токенов больше нет.Поэтому вы должны проверить возвращаемое значение, например:

if( (token = strtok(c,":")) != NULL ) 
    strcpy(a.name1,token);
else
   // token is NULL, there is no more tokens, end of string reached
   // you can return or do something else
1 голос
/ 27 марта 2019

Как правило, strtok используется в цикле. Например:

char *token = strtok(input_string, ".");
while(token != NULL) {
    //do code
    token = strtok(NULL, ".");
}

Таким образом, цикл заканчивается, когда происходит первый неудачный анализ. strtok должен продолжать возвращать NULL после конца входной строки каждый раз, когда вы ее используете, так что это не должно вызывать проблему, но это может быть.

Наиболее вероятная проблема, на мой взгляд, связана с тем, как вы используете strtok в strcpy. Возможно, strcpy завершается ошибкой, поскольку исходная строка имеет значение NULL. Что бы я сделал, если вы не хотите использовать цикл:

token = strtok(NULL, ":");
strcpy(a.name2, token);

Таким образом, вы гарантируете, что это не пустой указатель перед попыткой копирования. strcpy работает с пустой строкой (""), но не работает с указателем NULL.

Другая вещь, которую вы можете захотеть проверить, это то, что строки назначения (a.name2 и т. Д.) Выделены достаточно места. В противном случае это также может вызвать ошибку сегмента.

...