Не удается получить последний токен из буфера файлов
Я написал некоторый код, который читает текстовый файл и загружает каждую строку в буфер. Затем этот буфер обрабатывается с использованием функции strtok() с "," в качестве разделителя. Я получаю первые 3 токена просто отлично, но не могу получить последний токен. Это первый раз, когда я столкнулся с этим. При последнем вызове strtok(), когда я должен получить указатель на последний токен, strtok() возвращает ноль.
Частичный код:
for(j = 0, token = strtok(buffer, del); token != NULL; token = strtok(NULL, del), j++) {
printf("j: %d, token: %s\n",j, token);
switch(j) {
case 0:
index = fnv1aHash(token, (reqdata_len-1));
t_indices[i] = index;
addNode(&(table[index]));
table[index][0].course = (char *) malloc(1 + strlen(token));
strcpy(table[index][0].course, token);
break;
case 1:
table[index][0].category = (char *) malloc(1 + strlen(token));
strcpy(table[index][0].category, token);
break;
case 2:
strcpy(prereqbuff, token);
addPrereqs(prereqbuff, &(table[index][0].prereqs));
break;
case 3:
table[index][0].notes = (char *) malloc(1 + strlen(token));
strcpy(table[index][0].notes, token);
break;
}
}
Оператор switch предназначен только для управления тем, что и куда идет в структуре, которая организует информацию о строках по столбцам (разделенные запятыми). Таким образом, образец строки будет выглядеть так:
Words words,Wordswords,Words,Words\n // (where \n represents a new line)
Я пытался добавить \ n в качестве разделителя, но это не помогло. Я даже не попадаю внутрь "case 3:", так как токен указывает на ноль.
ЗАКЛЮЧИТЕЛЬНОЕ РЕДАКТИРОВАНИЕ
Я понял мою проблему. addPrereqs() вызывает strtok внутри себя, и, конечно, это означает, что в моей основной функции портится мой первоначальный вызов strtok. Я читал, что можно использовать strtok_r() в качестве обходного пути. В конце концов, я вызвал strtok() еще раз перед вызовом addPrereqs () и сразу же использовал этот токен для того, чего изначально хотел. Соответствующий раздел кода ниже:
for(j = 0, token = strtok(buffer, del); token != NULL; token = strtok(NULL, del), j++) {
switch(j) {
case 0:
index = fnv1aHash(token, (reqdata_len-1));
t_indices[i] = index;
addNode(&(table[index]));
table[index][0].course = (char *) malloc(1 + strlen(token));
strcpy(table[index][0].course, token);
break;
case 1:
table[index][0].category = (char *) malloc(1 + strlen(token));
strcpy(table[index][0].category, token);
break;
case 2:
strcpy(prereqbuff, token);
token = strtok(NULL, del);
table[index][0].notes = (char *) malloc(1 + strlen(token));
strcpy(table[index][0].notes, token);
addPrereqs(prereqbuff, &(table[index][0].prereqs));
break;
}
}
2 ответа
Это calloc(strlen(token), sizeof(char));
это проблема,
- Не использовать
calloc()
если вы перезапишете нули немедленно. Что еще более важно, вам нужно еще 1 байт для хранения строки.
table[index][0].notes = malloc(1 + strlen(token));
в вашем коде,
strcpy()
пишет окончание'\0'
в недопустимом месте, что вызывает неопределенное поведение.
Я сделал минимальный компилируемый пример вашего кода (из опубликованных деталей), и в этом просто нет ничего плохого - как изложено в вопросе. Извлекает все жетоны. Я бы критиковал, однако, то, как он сложен - ужасная смесь for
и подразумевается while
а также switch
,
#include <stdio.h>
#include <string.h>
int main(void) {
int j;
char *token;
char buffer[] = "Words words,Wordswords,Words,Words\n";
char del[] = ",\n";
for(j = 0, token = strtok(buffer, del); token != NULL; token = strtok(NULL, del), j++) {
printf("j: %d, token: %s\n",j, token);
switch(j) {
case 0:
break;
case 1:
break;
case 2:
break;
case 3:
break;
}
}
return 0;
}
Выход программы:
j: 0, token: Words words
j: 1, token: Wordswords
j: 2, token: Words
j: 3, token: Words