【问题标题】:How do I loop through each line of a file? [duplicate]如何循环遍历文件的每一行? [复制]
【发布时间】:2013-10-05 22:56:10
【问题描述】:

我正在尝试为文件中的每一行的新结构分配内存,但是当文件为空时,我的循环仍会分配一次内存。问题是使用 while(!feof(file)),但我无法找出 while 循环的替代检查。

循环如下所示:

while(!feof(f))
{
    p = (struct PlayerTime*)malloc(sizeof(struct PlayerTime));
    head = p;
    fscanf(f, "%f %s", &p->seconds, p->name);
    p = p->next;
}

指针和结构都是在循环之前定义的,如果文件中没有任何内容,我只是不知道如何让它不循环。

【问题讨论】:

  • 除了上面的链接,请参阅接受答案here的cmets。

标签: c file


【解决方案1】:
  1. feof(f) 表示 EOF 尚未被击中
  2. fscanf 命中 EOF 并失败
  3. feof(f) 停止循环,因为 EOF 已被命中

正确的做法:

while (fscanf(f, "%f %s", &p->seconds, p->name) == 2) {
    ...
}

提示:还要花更多时间思考应该何时以及如何分配内存,可能发生什么情况以及应该如何处理。

【讨论】:

    【解决方案2】:

    这已经被讨论过令人作呕feof 不会告诉您文件是否会在下一次读取时完成,而是告诉您是否已尝试读取并由于文件结束而失败。

    在您的情况下,解决方案可以是检查读取是否失败(通过检查fscanf 的返回值),在这种情况下释放结构;这也使您的代码更加健壮,因为它还会检查 EOF 以外的错误(例如 IO 错误、无效数据格式……)。

    顺便说一句,p = p->next 不会做你所期望的。如果你正在“动态”构建一个链表,你可以这样做:

    // Allocate the space for the first element
    struct PlayerTime *head=malloc(sizeof(*head));
    // p will always point to a pointer to the element to be filled;
    // let's start with the head
    struct PlayerTime **p=&head;
    // Try to read
    while(fscanf(f, "%f %s", &((*p)->seconds), (*p)->name)==2)
    {
        // If we are here, the last read was successful
        // Move p to the pointer to the next element
        p = &((*p)->next);
        // ... and allocate the space for such element
        *p = malloc(sizeof(**p));
    }
    // After exit, there's an extra element that we allocated but we couldn't read
    // Free it
    free(*p);
    // And put the relevant pointer to NULL
    // (it will terminate the list, or set head to NULL if no element has been read)
    *p=NULL;
    

    【讨论】:

      猜你喜欢
      • 2016-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-29
      • 2017-09-08
      • 2016-07-20
      • 2019-06-12
      • 1970-01-01
      相关资源
      最近更新 更多