【发布时间】:2015-02-10 01:33:02
【问题描述】:
程序(在 c++ 中)必须按顺序在文件中写入文本。但有时需要在特定的行号上写一些东西。有没有办法在不循环整个文件的情况下导航到特定的行号,如果有,它的复杂性是什么?有没有类似 fseek 的东西?
【问题讨论】:
程序(在 c++ 中)必须按顺序在文件中写入文本。但有时需要在特定的行号上写一些东西。有没有办法在不循环整个文件的情况下导航到特定的行号,如果有,它的复杂性是什么?有没有类似 fseek 的东西?
【问题讨论】:
除非您的文件是固定长度的记录,否则没有快速定位行的方法。
对于可变长度的文本行,您必须读取每个字符以确定它是否是行结束字符。如果是,则增加行号。
如果您需要经常按行号访问行,您可能需要构建一个记录表。您只需要执行一次。
编辑 1:
您可以在创建文件时构建行位置表。在编写文本行之前,读取并存储文件位置。
顺便说一句,您可以覆盖文件中的文本,但不能将文本插入文件(追加除外)。要插入文本,您必须首先将所有原始数据写入新文件,写入新文本,然后写入所有剩余文本。
【讨论】:
seek()和truncate()来避免在插入点之前重写数据(用于插入文本)。
典型的原始文本文件的格式是描述每一行的字节序列,然后是行结束标记(在某些系统上是一个字节,在其他系统上是两个)。然后下一行立即开始。
文件通常以结束行标记结束。
如果您的文件是基于此格式化的,则没有快速的方法可以找到一行,或者将其替换为具有完全相同字节数的行之外的任何内容。
这种格式的优点是有很多很多的工具可以读取它。
但是,这不一定是您的格式。一种很容易找到行并且同样替换行的格式是非常可写的。这不会是微不足道的,但也不是棘手的。
要获得简单的方法,请抓住STXXL。遗憾的是,我在那里没有看到一个随机访问的廉价中间插入删除容器(就像一个自平衡树,每个节点都存储了子树大小)。但也许有。
【讨论】:
你需要 GotoLine() 函数。
例如,您有文件 dummy.txt,并且您想要导航到第 10 行。 所以你可以这样做
fstream file("dummy.txt");
GotoLine(file, 10);
【讨论】:
ofstream myfile("foo.txt");
int lineNumber = 123;
for(int i=0;i<lineNumber-1;i++) myfile << "\n";
myfile << "Here I am on line number " << lineNumber << endl;
【讨论】: