使用fgets和strtok从文件中读取和解析行

我在使用相当基本的代码时遇到了麻烦。 我需要从下面显示的文件中读取每一行,用strtok将它分成3部分,并将每个部分存储到一个数组中。 “目标”和“助手”的数组工作正常,但由于某种原因,整个名称数组都填充了从文件中读取的姓氏。

输入文件:

Redden 2 0 Berglund 5 2 Jackman 2 0 Stewart 4 0 Oshie 3 5 McDonald 2 4 Pietrangelo 2 7 Perron 2 6 Tarasenko 5 5 

相关代码:

 int main(int argc, char* argv){ FILE* inFile = fopen(argv[1],"r"); char ** nameArray; int * goalArray; int * assistArray; int size = countLinesInFile(inFile); allocateMemory(&goalArray, &assistArray, &nameArray, size); readLinesFromFile(inFile, goalArray, assistArray, nameArray, size); } void allocateMemory(int** goals, int** assists, char*** names, int size) { *goals = malloc(size*sizeof(int)); *assists = malloc(size*sizeof(int)); *names = malloc(size*sizeof(char *)); int i; for(i=0; i<size; i++) { *(*names + i) = calloc(MAX_NAME,sizeof(char)); } } void readLinesFromFile(FILE* fPtr, int* goals, int* assists, char** names, int numLines) { int i; char * buffer = malloc(MAX_LINE*sizeof(char)); for(i = 0; i<numLines; i++) { if(fgets(buffer, MAX_LINE, fPtr)!= NULL) { names[i] = strtok(buffer, " \n"); goals[i] = atoi(strtok(NULL, " \n")); assists[i] = atoi(strtok(NULL, " \n")); } } } 

出于某种原因,nameArray [0-9]都包含“Tarasenko”,对此的任何帮助将不胜感激。

strtok返回一个指向包含下一个标记的以null结尾的字符串的指针。 要实际复制此令牌,您应该使用strcpy

 strcpy(names[i], strtok(buffer, " \n")); strcpy(goals[i], atoi(strtok(NULL, " \n"))); strcpy(assists[i], atoi(strtok(NULL, " \n"))); 

另请注意,代码中存在内存泄漏:

 void readLinesFromFile(/*...*/) { char * buffer = malloc(MAX_LINE*sizeof(char)); // ... fgets(buffer, MAX_LINE, fPtr); // ... } 

您通过调用malloc动态分配buffer ,但不释放此内存。 不要忘记在指向malloc分配的内存的指针上调用free() 。 但在这种情况下,具有自动存储持续时间的arrays将是更好的选择:

 void readLinesFromFile(/*...*/) { char buffer[MAX_LINE]; // ... fgets(&buffer, MAX_LINE, fPtr); // ... } 

您没有复制出名称,只需将strtok返回的指针放入数据结构中即可。 您最终会得到一个数据结构,其中包含指向buffer指向的相同内存的相同指针。 由于buffer的内容在每次遍历循环时都会被修改,因此最终会得到一堆指向上次通过的指针。