【问题标题】:Saving off the current read position so I can seek to it later保存当前的读取位置,以便稍后查找
【发布时间】:2012-05-27 00:49:00
【问题描述】:

我有一个程序可以读取具有已知结构的文本文件。

例如,我在文件的每一行都有两个整数和一个字符串。

当我在循环中使用fscanf 时,我可以重新获得上面提到的n 结构。如何获取数据文件中的当前位置,以便将其存储在某个位置,然后从我之前离开的位置继续读取我的文本文件。

【问题讨论】:

  • ftell 和 fseek 是对的,但我记得您不需要它们,只需编写一个 while 循环并按顺序读取即可满足您的需求。如果我错了,请纠正我。

标签: c io scanf


【解决方案1】:

使用 ftell() 函数。它将返回文件中的偏移量。

unsigned long position = ftell(file);

但是,对于文本文件,知道 ftell() 可以报告错误的位置非常重要,除非内部缓冲区已被清除。为此,

unsigned long position;
fflush(file);
position = ftell(file);

稍后,您可以使用 fseek

fseek(file,position,SEEK_SET);

ftell() 告诉使用较早文件开头的偏移量。在这里,您使用 SEEK_SET 来指示您传递的位置是从文件的开头开始。

编辑:理查德问 fflush() 做了什么。当您读取或写入文件时,C 库几乎总是保留信息的缓冲区。 “刷新”该缓冲区是将其写入磁盘,以保存任何更改。由于允许 C 库处理文本文件的方式,此缓冲区可能会导致 ftell() 报告错误的位置,除非缓冲区被刷新。这就是 fflush() 所做的。

【讨论】:

  • 对于文本文件,知道ftell() 可以报告错误位置非常重要,除非内部缓冲区已被清除 嗯?不是the C standard:“ftell 函数获取流指向的流的文件位置指示符的当前值。...对于文本流,其文件位置指示符包含未指定的信息,可由 fseek 函数用于返回流的文件位置指示器到 ftell 调用时的位置;...."
  • 您不会在update mode with a +? 中打开文件“当以更新模式打开文件时('+' 作为上述模式参数值列表中的第二个或第三个字符),两者可以在关联的流上执行输入和输出。但是,在没有对 fflush 函数或文件定位函数(fseek、fsetpos 或 rewind)的中间调用的情况下,输出不应直接跟随输入,并且输入不应直接跟随后跟输出,没有对文件定位函数的干预调用"
  • And NEVER use fflush() on a stream in input mode: "如果流指向输出流或更新流,其中没有输入最近的操作,fflush 函数会导致该流的任何未写入数据被传递到主机要写入文件的环境;否则,行为未定义。"
【解决方案2】:

使用ftell 存储文件的位置,fseek 稍后返回。

【讨论】:

    【解决方案3】:

    ftellfseek 的过程很简单。查看示例代码

    int i, int1, int2;
    FILE *file;
    char *str1;
    
    ...
    // read 10 lines
    for(i=0; i<10; i++){
       fscanf(file, "%d %d %s", int1, int2, str1);
    }
    
    // save the position;
    pos = ftell(file);
    
    // close the file
    fclose(file)
    
    ...
    // later go to that same location after opening the same file
    fseek(file, pos, 0);
    
    // continue reading
    fscanf(file, "%d %d %s", int1, int2, str1);
    

    【讨论】:

      【解决方案4】:

      在读取记录之前在ftell 之前执行fflush 以获取文件位置,从而搞砸下一个记录。在我的应用程序中,只有 ftell 和后来的 fseek 为我工作。

      我的错误是尝试使用fsetpos 而不是fseek。前者的论点很奇怪,通过强制将ftell 输出到其中导致我的应用程序立即退出(不是错误,但显然是我没想到这么快的EOF)。

      【讨论】:

        【解决方案5】:

        如果我理解正确,您正在寻找ftell 函数

        【讨论】:

          【解决方案6】:

          ftell() 返回一个 long,这对于小文件是可以的。

          对于较长的文件,我使用uint64_t pos = lseek(fd, 0, SEEK_CUR),因为lftell() 似乎不存在。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2022-10-14
            • 2019-09-09
            • 2015-07-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-08-31
            • 2010-10-25
            相关资源
            最近更新 更多