如何逆转文件中的行顺序

我们怎样才能尊重文件中的行顺序而不是行本身。 文件可以变得很大。

不应该假设线的长度。

输入:

this is line1 this is line2 this is line3 

示例输出:

 this is line3 this is line2 this is line1 

我虽然使用另一个文件作为缓冲区,就像堆栈数据结构一样,但实际上并没有随处可见。

有什么想法吗?

从两端开始读入文件的大块。 在这些块中,交换最后一行的第一行,然后移动两个指针以跟踪您的位置。 填写时写出每个块。 当两个指针在中间相遇时,你就完成了。

不要试图修改块,这会使事情变得更复杂。 使用四个块,第一个读取块,第一个写入块,最后一个读取块和最后一个写入块。 每个写入块完成后,写出来。 当每个读取块耗尽时,请读取另一个读取块。 小心不要覆盖你还没读过的东西!

它应该相当简单,只是单调乏味。 如果您不需要它是最佳的,您可以向后读取块并写出新文件,然后将其移到现有文件的顶部。

如果文件不适合内存,那么这是一个两遍过程。 第一遍,你读取文件的块(尽可能多的行适合内存),然后以相反的顺序将它们写入临时文件。 所以你有了:

 while not end of input read chunk of file into array of lines write lines from array to temporary file, in reverse order end while 

当你完成第一遍时,你将拥有一堆临时文件:temp1.txt,temp2.​​txt,temp3.txt … tempN.txt。

现在打开追加的最后一个文件(tempN.txt),然后开始以相反的顺序附加文件。 所以你有了:

 open fileN for append fileno = N-1 while fileno > 0 append file_fileno to fileN fileno-- end while 

然后重命名tempN.txt并删除其他临时文件。

顺便说一句,您可以使用操作系统提供的串联实用程序执行步骤2.例如,在Windows上,您可以将步骤2替换为:

 copy /A file4.txt+file3.txt+file2.txt+file1.txt mynewfile.txt 

其他平台上有类似的实用程序。

但是,您可能会遇到命令行长度限制。

它可以通过两个简单的步骤完成:

第1步:反转所有文件

第2步:反转每一行

 step:0 1 2 --------------------- abc zyx xyz 1234 => 4321 => 1234 xyz cba abc 

编辑 :这是一个完整的解决方案:

 #include  #include  #include  #define BUFFSIZE 4098 /*make sure this is larger then the longest line...*/ using namespace std; bool reverse_file(const char* input, const char* output) { streamsize count=0; streamoff size=0,pos; char buff[BUFFSIZE]; ifstream fin(input); ofstream fout(output); if(fin.fail() || fout.fail()){ return false; } fin.seekg(0, ios::end); size = fin.tellg(); fin.seekg(0); while(!fin.eof()){ fin.read(buff, BUFFSIZE); count = fin.gcount(); reverse(buff,buff+count); pos = fin.tellg(); if(pos<0) { pos = size; } fout.seekp(size - pos); fout.write(buff,count); } return true; } bool reverse_file_lines(const char* input, const char* output) { streamsize count=0; char buff[BUFFSIZE]; ifstream fin(input); ofstream fout(output); if(fin.fail() || fout.fail()){ return false; } while(!fin.eof()){ fin.getline(buff, BUFFSIZE); /*if BUFFSIZE is smallest then line size gcount will return 0, but I didn't handle it...*/ count = fin.gcount(); if(buff[count-1]==0)count--; reverse(buff,buff+count); fout.write(buff,count); if(!fin.eof()){ fout<