Reading and parsing lines from a file with fgets and strtok

元气小坏坏 提交于 2019-12-19 09:08:09

问题


I'm having trouble with a fairly basic bit of code. I need to read each line from the file shown below, split it up into the 3 parts with strtok, and store each part into an array. The arrays for "goals" and "assists" are working perfectly, but for some reason the entire name array is filled with the last name read from the file.

Input file:

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

Relevant code:

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"));
    }
  }
}

For some reason, nameArray[0-9] all contain "Tarasenko", and any help with this would be greatly appreciated.


回答1:


strtok returns a pointer to a null-terminated string containing the next token. To actually copy this token, you should use strcpy:

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

Also note that there is a memory leak in your code:

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

You dynamically allocate the buffer by calling malloc, but you don't free this memory. Don't forget to call free() on a pointer pointing to the memory that has been allocated by malloc. But in this case, the array with automatic storage duration would be a better choice:

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



回答2:


You didn't copy out the name, you just put the pointer returned by strtok into your data structure. You are just ending up with a data structure full of identical pointers to the same memory pointed to by buffer. Since the contents of buffer get modified on every pass through the loop, you end up with a bunch of pointers to whatever it was the last time through.



来源:https://stackoverflow.com/questions/15033140/reading-and-parsing-lines-from-a-file-with-fgets-and-strtok

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!