向后读取文件(最后一行)

har*_*ari 6 c file

文件看起来像这样:

abcd
efgh
ijkl

我想使用C它来读取文件,以便它首先读取最后一行:

ijkl
efgh
abcd

我似乎无法找到不使用array存储的解决方案.请帮忙.

edit0: 谢谢你的所有答案.只是为了让你知道,我是创建这个文件的人.那么,我可以以相反的顺序创建它吗?那可能吗?

mu *_*ort 9

它是这样的:

  1. 使用在文件结束前寻找一个字节fseek.不能保证最后一行会有EOL,所以最后一个字节并不重要.
  2. 使用读取一个字节fgetc.
  3. 如果该字节是EOL,那么最后一行是一个空行而你拥有它.
  4. fseek再次使用后退两个字节并检查该字节fgetc.
  5. 重复上述步骤,直到找到EOL.当您有EOL时,文件指针将位于下一行(从结尾)行的开头.
  6. ...
  7. 利润.

基本上你一直在做(4)和(5),同时在找到一条线的开头时跟踪你的位置,这样你就可以在开始下一行开始扫描之前找回那里.

只要您在文本模式下打开文件,就不必担心Windows上的多字节EOL(感谢提示Lutz先生).

如果碰巧给你一个不可搜索的输入(例如管道),那么除非你想先将输入转储到临时文件,否则你运气不好.

所以你可以做到,但它相当难看.

mmap如果你有mmap可用的话,你可以使用和指针做同样的事情,并且你正在使用的"文件"是可映射的.这种技术几乎是一样的:从最后开始然后向后找到前一行的结尾.


Re:"我是创建这个文件的人.那么,我可以以相反的顺序创建它吗?这可能吗?"

你会遇到同样的问题,但情况会更糟.C中的文件本质上是连续的字节列表,从开头开始到结尾; 你正试图反对这个基本的财产,反对基本面永远不会有趣.

您真的需要纯文本文件中的数据吗?也许您需要text/plain作为最终输出但是一直都是如此?您可以将数据存储在索引的二进制文件(甚至可能是SQLite数据库)中,然后您只需担心将索引保留(或窗口化)在内存中并且这不太可能是一个问题(如果是,请使用一个"真正的"数据库); 然后,当你拥有所有的线条时,只需反转索引即可.

  • 您的解决方案效率不高,因为`fseek`是一个慢速操作,而您正在为文件中的每个字节执行此操作. (2认同)
  • 标准的`f*` IO 函数,当`FILE *` 以文本(非二进制)模式打开时,会自动为您进行EOL 转换。 (2认同)