文件看起来像这样:
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/6922829/