如何遍历文件的每一行?

时间:2013-10-05 22:56:10

标签: c file

我正在尝试为文件中的每一行分配一个新结构的内存,但是当文件为空时,我的循环仍会分配一次内存。问题是使用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;
}

指针和结构都是在循环之前定义的,如果文件中没有任何内容,我就无法弄清楚如何让它不循环。

2 个答案:

答案 0 :(得分:0)

  1. feof(f)EOF还没有被击中
  2. fscanf点击EOF并失败
  3. feof(f)停止循环,因为EOF已被点击
  4. 正确方法:

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

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

答案 1 :(得分:0)

已经讨论过 ad nauseam ; feof没有告诉您文件是否会在下次读取时完成,但是如果读取已经尝试并且由于文件结束而失败。

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

顺便说一句,p = p->next没有按照您的意愿行事。如果您正在构建一个链接列表"即时#34;您可以这样做:

// 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;