我们如何尊重文件中的行顺序而不是行本身。 文件可以变得很大。
不应该假设线的长度。
输入:
this is line1
this is line2
this is line3
示例输出:
this is line3
this is line2
this is line1
我虽然使用另一个文件作为缓冲区,就像堆栈数据结构一样,但却无法真正随意使用它。
对此有何想法?
答案 0 :(得分:3)
从两端开始读入文件的大块。在这些块中,交换最后一行的第一行,然后移动两个指针以跟踪您的位置。填写时写出每个块。当两个指针在中间相遇时,你就完成了。
不要尝试修改块,这会使事情变得更复杂。使用四个块,第一个读取块,第一个写入块,最后一个读取块和最后一个写入块。每个写块都完成后,写出来。当每个读取块耗尽时,请读取另一个读取块。小心不要覆盖你还没读过的东西!
它应该相当简单,只是单调乏味。如果您不需要它是最佳的,您可以向后读取块并写出一个新文件,然后将其移到现有文件的顶部。
答案 1 :(得分:1)
如果文件不适合内存,那么这是一个两遍过程。第一遍,你读取文件的块(尽可能多的行适合内存),然后以相反的顺序将它们写入临时文件。所以你有:
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
其他平台上也有类似的实用程序。
但是,您可能会遇到命令行长度限制。
答案 2 :(得分:0)
可以通过两个简单的步骤完成:
第1步:撤消所有文件
第2步:反转每一行
step:0 1 2
---------------------
abc zyx xyz
1234 => 4321 => 1234
xyz cba abc
编辑:这是一个完整的解决方案:
#include <iostream>
#include <fstream>
#include <algorithm>
#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<<endl;
}
}
return true;
}
int main()
{
reverse_file("test.in", "test.tmp");
reverse_file_lines("test.tmp","test.out");
return 0;
}