我正在构建一个大型文件I / O库,目前正在努力解决getline()的互操作性问题并写入文件。我的下面的问题很像这个问题,遗憾的是,这个问题仍未得到答复:C++ After I use getline to read from a file I can no longer write to the txt file
一旦我使用了getline(),我就无法再写入文件了。使用getline()的读取请求将继续运行,但写入请求将失败。但是,如果我注释掉getline()的使用,写操作将会成功。
我的代码发布在下面。我注意到在第一次写入尝试后,failbit被激活。但是,我不知道发生这种情况的原因,因为如果我删除了getline()操作它就不会激活。
我应该清楚 - 我可以完全从现有文件(包含两行)中读取。但是,我无法写入该文件,除非我删除了getline()语句。
任何帮助都是一如既往的。
// Includes
#include <fstream>
#include <iostream>
#include <string>
// Namespace
using namespace std;
int main(){
// filestream object
fstream workFile("testdoc.txt"); //fstream uses ios::in | ios::out by default
// note that I have tried including ios::in | ios::out to no avail
// read from file
string grabbedLine;
getline(workFile, grabbedLine);
cout << "Line #1: " << grabbedLine << endl;
// write to file
workFile<< "Here is some output (#1)" << endl;
// read from file
getline(workFile, grabbedLine);
cout << "Line #2: " << grabbedLine << endl;
// write to file
workFile<< "Here is some output (#2)" << endl;
// wait for some input...
getchar();
}
Current console output (as expected from text file):
Line #1: This is line#1
Line #2: This is line#2
答案 0 :(得分:3)
基于一些实验,看起来<<
运算符期望偏移量位于文件的末尾。我无法准确地解释它,但似乎在你调用getline()
之后,偏移量不是预期的。我可以通过添加以下行来写入文件:
workFile.seekg(ios_base::end);
在写入文件之前。但是,这会将偏移量放在文件末尾,然后不能正确读取第二行。
我认为你想要做的是打开两个文件句柄,一个你将阅读的文件句柄,一个你要写的句柄:
int main(){
// filestream object
fstream workFileRead("testdoc.txt", ios_base::in);
fstream workFileWrite("testdoc.txt" , ios_base::app | ios_base::out);
// read from file
string grabbedLine;
getline(workFileRead, grabbedLine);
cout << "Line #1: " << grabbedLine << endl;
// write to file
workFileWrite << "Here is some output (#1)" << endl;
// read from file
getline(workFileRead, grabbedLine);
cout << "Line #2: " << grabbedLine << endl;
// write to file
workFileWrite<< "Here is some output (#2)" << endl;
// wait for some input...
getchar();
}
答案 1 :(得分:2)
我知道现在这是一个旧帖子,但我遇到了同样的问题,并且在Google搜索中一直没有回答这个问题。 ......
我设法让这个工作。如链接帖子中所述,使用getline()读取文件末尾会设置Fail位。这需要被清除,并且在写入之前将指针设置到正确的位置以便写入... 例如我的代码读取文件的最后一行然后写一些东西:
fstream myfile;
char line[10];
string myText;
myfile.open("test.txt", ios::in | ios::out);
while ( myfile.getline(line,10) )
{ myText = line; } //myText is left storing the last line
myfile.clear();
myfile.seekp(0, ios::end);
myfile << "Writing to this file!!!" << endl;
myfile.close();
答案 2 :(得分:1)
fstream只有一个流位置,由读写共享。因此,在阅读和写作之间进行转换时,您实际上必须进行搜索。您可以使用其中一个tell函数来保存当前的读取或写入位置,然后在想要继续时回溯。
打开文件两次以获得两个流位置可能不是一个好主意。如果操作系统允许您完全执行此操作,则可能会以各种方式混淆文件内容。
答案 3 :(得分:0)
考虑<<
对文件的作用:它写入它,并且因为你可以从中读取,我们知道它被打开以追加。 )否则,文件将首先被截断,并且读取将不会成功。)当您将数据写入文件时,文件偏移量自动位于文件的末端,所以现在没有什么更多阅读。
现在,您可以使用lseek(2)或包装它的方法(例如fstream::tellg
)来解决这个问题,但我打赌您想要想要的是创建用于输出的临时文件,将所有内容写入该文件,然后移回临时文件以替换原始文件。
<强>更新强>
对不起,现在已经很晚了,我扭转了这个问题的感觉。如果根本没有发生任何事情,那么很可能你没有一个可以写的文件。你检查过fail
标志了吗?请参阅iostream::fstream类的文档,其中包含:
构造fstream的对象 类。这意味着初始化 相关的filebuf对象和 对它的构造函数的调用 将filebuf对象作为基类 参数。
另外,当第二个 使用构造函数版本 流与物理相关联 文件就像调用该成员一样 函数打开使用相同的参数 是的。
如果构造函数不成功 在打开文件时,对象是 仍然创建,虽然没有文件 与流缓冲区相关联 流的failbit已设置(可以 用继承的成员检查 失败)。
答案 4 :(得分:0)
该文件很可能无法打开输出,因此不是
fstream workFile("testdoc.txt");
使用以下
fstream workFile("testdoc.txt", fstream::in | fstream::out);
答案 5 :(得分:0)
这可以通过使用read()
函数而不是getline()
来解决。