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

4
我遇到了一个相当基础的代码问题。我需要从下面显示的文件中读取每一行,用strtok将其分成3个部分,并将每个部分存储到一个数组中。 "goals" 和 "assists" 的数组完美地工作了,但由于某种原因,整个“name”数组都填满了从文件中读取的最后一个名字。
输入文件:
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”,非常感谢任何帮助。
2个回答

1
你没有复制名称,而是将strtok返回的指针放入数据结构中。最终你只会得到一个数据结构,其中包含了相同的指向buffer所指内存的指针。由于在每次循环中buffer的内容都会被修改,因此你最终会得到一堆指向上一次循环时它所指向的任何内容的指针。

1

strtok返回一个指向包含下一个标记的以空字符结尾的字符串的指针。要实际复制此标记,您应该使用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()。但在这种情况下,具有自动存储期的数组可能是更好的选择:
void readLinesFromFile(/*...*/)
{
    char buffer[MAX_LINE];
    // ...
    fgets(&buffer, MAX_LINE, fPtr);
    // ...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接