我试图读取和写入文件,因为我循环了它的行。在每一行,我将进行一次评估,以确定是否要将其写入文件或跳过它并转到下一行。这基本上是我到目前为止的骨架。
void readFile(char* fileName)
{
char line[1024];
fstream file("test.file", ios::in | ios::out);
if(file.is_open())
{
while(file.getline(line,MAX_BUFFER))
{
//evaluation
file.seekg(file.tellp());
file << line;
file.seekp(file.tellg());
}
}
}
当我读到这些内容时,我似乎遇到了复制到行变量中的字符串起始索引的问题。例如,我可能期望行变量中的字符串为&#34; 000/123 / FH /&#34;但它实际上是作为&#34; 123 / FH /&#34;。我怀疑我有file.seekg(file.tellp())和file.seekp(file.tellg())的问题,但我不确定它是什么。
答案 0 :(得分:3)
从您的代码 [1] 和问题描述中不清楚文件中的内容以及您期望的原因&#34; 000/123 / FH /&#34;,但我可以声明getline
函数是缓冲输入,并且您没有代码来访问缓冲区。通常,不建议同时使用缓冲和非缓冲的i / o,因为它需要深入了解缓冲机制,然后依赖于该机制,不会随着库的升级而改变。
您似乎想要执行字节或字符 [2] 级别操作。对于小文件,您应该将整个文件读入内存,操作它,然后覆盖原始文件,需要打开,读取,关闭,打开,写入,关闭序列。对于大型文件,您需要使用fread
和/或其他一些较低级别的C库函数。
这样做的最好方法是,因为你正在使用C ++,就是创建你自己的类来处理读取并包括行分隔符 [3] 到其中一个架式循环缓冲区(使用malloc或插件分配器,就像类似STL的容器一样)或循环缓冲区,作为模板在静态分配的字节数组上开发(如果你想要高速度和低资源利用率) 。尺寸必须至少与后一种情况下的最长线一样大。 [4]
无论哪种方式,您都希望添加到类中以二进制模式打开文件,并公开所需的方法以对任意行进行行级操作。有人说(我个人同意)在C ++中利用Bjarne Stroustrup的类封装是类更容易仔细测试。这样的行操作类将封装随机访问C函数和无缓冲的i / o,并留下最大化速度的机会,同时允许在系统和应用程序中使用即插即用。
备注强>
[1]寻找当前位置只是测试函数,并且在代码的当前状态下还没有重新定位当前文件指针。
[2]请注意,在当今的计算环境中,字符和字节级操作之间存在差异,其中utf-8或其他一些unicode标准现在在许多域中比ASCII更常见,尤其是网络
[3]请注意,行分隔符取决于操作系统,版本,有时还取决于设置。
[4]循环缓冲区在速度方面的优势在于,您可以一次使用fread读取多行,并使用快速迭代查找下一行。
答案 1 :(得分:0)
您正在阅读和写入您可能最终在文件中出现重复行的文件。
你可以发现this非常有用。想象你第一次到达while循环。并从文件的开头file.getline(line,MAX_BUFFER)
开始。现在get指针(用于读取)将MAX_BUFFER
个位置移动到文件的开头(起点)
在“您确定”后写回文件seekp()
有助于针对参考点指定您要写入的位置,语法:file.seekp(num_bytes,"ref");
其中{{1}将是ref
在阅读后的代码中
ios::beg(beginning), ios::end, ios::cur(current possition in file)
找到一种方法,使用 while(file.good())
{
file.getline(line,MAX_BUFFER);
...
if(//for some reasone you want to write back)
{
// set put-pointer to location for writing
file.seekp(num_bytes, "ref");
file << line;
}
//set get-pointer to desired location for the next read
file.seekg(num_bytes, "ref");
}
来引用与引用相关的位置。
答案 2 :(得分:0)
从Douglas Daseeco的回复中获取灵感,我通过简单地读取现有文件,将其行写入新文件,然后重命名新文件以覆盖原始文件来解决我的问题。下面是我的解决方案的骨架。
char line[1024];
ifstream inFile("test.file");
ofstream outFile("testOut.file");
if(inFile.is_open() && outFile.is_open())
{
while(inFile.getline(line,1024))
{
// do some evaluation
if(keep)
{
outFile << line;
outFile << "\n";
}
}
inFile.close();
outFile.close();
rename("testOut.file","test.file");
}