文件看起来像这样:
abcd
efgh
ijkl
我想使用 C
读取文件,以便它首先读取最后一行:
ijkl
efgh
abcd
我似乎找不到不使用数组
进行存储的解决方案。请帮忙。
编辑0: 感谢所有的答案。只是为了让您知道,我是创建此文件的人。那么,我可以以相反的顺序创建吗?这可能吗?
最佳答案
事情是这样的:
- 使用
fseek
在文件末尾之前查找一个字节。无法保证最后一行会有 EOL,因此最后一个字节并不重要。 - 使用
fgetc
读取一个字节. - 如果该字节是 EOL,那么最后一行是一个空行,您就拥有了它。
- 再次使用
fseek
向后移动两个字节并使用fgetc
检查该字节。 - 重复上述操作,直到找到 EOL。当您有 EOL 时,文件指针将位于下一行(从末尾开始)的开头。
- ...
- 利润。
基本上,您必须继续执行(4)和(5),同时跟踪找到行开头时所在的位置,以便您可以在开始扫描下一行的开头之前返回那里。
只要您以文本模式打开文件,您就不必担心 Windows 上的多字节 EOL(感谢 Lutz 先生的提醒)。
如果您碰巧获得了不可搜索的输入(例如管道),那么您就不走运了,除非您想先将输入转储到临时文件中。
所以你可以做到,但它相当难看。
您可以使用 mmap
做几乎相同的事情如果您有可用的 mmap
并且您正在使用的"file"是可映射的,则还有一个指针。技术几乎相同:从末尾开始,向后查找上一行的末尾。
回复:“我是创建此文件的人。那么,我可以以相反的顺序创建吗?这可能吗?”
您会遇到同样的问题,但情况会更糟。 C 中的文件本质上是字节的顺序列表,从开头开始一直到结尾;你试图违背这个基本属性,而违背基本属性从来都不是一件有趣的事。
您真的需要纯文本文件中的数据吗?也许您需要 text/plain 作为最终输出,但一直需要?您可以将数据存储在索引二进制文件(甚至可能是 SQLite 数据库)中,然后您只需担心将索引保留(或窗口化)在内存中,这不太可能成为问题(如果是,请使用“真实”数据库);然后,当您拥有所有行后,只需反转索引即可开始。
关于c - 向后读取文件(最后一行在前),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32662762/