【问题标题】:Reading and parsing lines from a file with fgets and strtok使用 fgets 和 strtok 从文件中读取和解析行
【发布时间】:2013-02-08 14:23:42
【问题描述】:

我在编写一段相当基本的代码时遇到了问题。我需要从下面显示的文件中读取每一行,用 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”,我们将不胜感激。

【问题讨论】:

    标签: c string io fgets strtok


    【解决方案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);
        // ...
    }
    

    【讨论】:

      【解决方案2】:

      你没有复制名字,你只是把strtok返回的指针放到你的数据结构中。您最终会得到一个充满相同指针的数据结构,这些指针指向buffer 指向的同一内存。由于buffer 的内容在每次循环时都会被修改,所以你最终会得到一堆指向上次循环的指针。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-03-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多