2

我正在构建一个大型文件 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() 的用法,写操作就会成功。

我的代码发布在下面。我注意到在第一次写入尝试后故障位被激活。但是,我不知道发生这种情况的原因,因为如果我删除 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
4

6 回答 6

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();
}
于 2011-02-06T04:47:36.553 回答
2

我知道这是一篇旧帖子,但我刚刚遇到了同样的问题,并一直在谷歌搜索中点击这个未答复的帖子。...

我设法让这个工作。如链接帖子中所述,使用 getline() 读取文件末尾会设置失败位。这需要清除,并且在写入成功之前将指针设置到正确的写入位置......例如我的代码读取文件的最后一行然后写一些东西:

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();
于 2012-11-12T01:10:11.133 回答
1

一个 fstream 只有一个流位置,由读写共享。因此,在阅读和写作之间切换时,您实际上必须进行搜索。您可以使用其中一个 tell 函数来保存您当前的读取或写入位置,然后在您想继续时回溯。

打开文件两次以获得两个流位置可能不是一个好主意。如果操作系统允许您这样做,您可能会以各种方式混淆文件内容。

于 2011-02-06T10:18:52.047 回答
0

想想对文件做了什么<<:它写入文件,并且由于您可以从中读取,我们知道它已打开以追加。)否则,文件会先被截断,读取不会成功。)当你将数据写入文件时,文件偏移量会自动在文件末尾,所以现在没有什么要读取的了。

现在,您可以使用lseek(2)或包装它的方法来编写自己的方式fstream::tellg,但我敢打赌,您真正想要的是创建一个临时文件用于输出,将所有内容写入该文件,然后移动temp 文件返回以替换原始文件。

更新

抱歉,来晚了,我把问题的意思颠倒了。如果根本没有发生任何事情,那么很可能您没有可以打开写入的文件。你检查过fail国旗吗?请参阅iostream::fstream类的文档,其中说:

构造 fstream 类的对象。这意味着关联的 filebuf 对象的初始化以及以 filebuf 对象作为参数调用其基类的构造函数。

此外,当使用第二个构造函数版本时,流与物理文件相关联,就好像调用了具有相同参数的成员函数 open。

如果构造函数没有成功打开文件,尽管没有文件与流缓冲区关联并且设置了流的失败位(可以通过继承成员失败检查),但仍会创建对象。

于 2011-02-06T04:21:20.243 回答
0

该文件很可能未打开以进行输出,因此而不是

fstream workFile("testdoc.txt");

使用以下

fstream workFile("testdoc.txt", fstream::in | fstream::out);
于 2011-02-06T04:30:51.423 回答
0

这可以使用read()function 来解决getline()

于 2018-07-13T18:09:40.663 回答