更改文件内容-这是g++ 4.7.2中的错误还是我做错了?

changing file content - is this a bug in g++ 4.7.2 or am I doing it wrong?

本文关键字:错误 错了 文件 g++ 这是      更新时间:2023-10-16

在编写一些代码来更新二进制文件中的位置时,我注意到一些奇怪的事情。考虑以下示例代码:

#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
    char tmp;
    string s;
    fstream fs;
    fs.open("test.txt", fstream::out);
    fs << "blub" << endl;
    fs.close();
    fs.open("test.txt", fstream::in);
    fs >> s;
    cout << s << endl;
    fs.close();
    fs.open("test.txt", ios::in|ios::out|ios::binary);
    if (!fs.is_open() || !fs.good())
        cerr << "could not open!" << endl;
    fs.read(&tmp, 1);
    fs.read(&tmp, 1);
    //fs.tellg(); //<-- required to fix for old g++?
    const char *c = "ah";
    fs.write(&c[0], 1);
    fs.write(&c[1], 1);
    fs.close();
    fs.open("test.txt", fstream::in);
    fs >> s;
    cout << s << endl;
}

在最近的g++版本中(至少在6.2.1中),我可以只读取然后写入一些字节而不会出现问题-在示例中,您可以得到正确的输出:

blub
blah
然后我用g++ 4.7.2编译代码,突然更新没有效果,即第二个输出仍然是"blub",除非我添加fs.tellg()或fs.tellp()。我发现了这个问题,但据我所知,这是Windows的限制,但我在Linux下工作。

现在我想知道,这是旧g++中的一个错误,还是我做错了,只是幸运地使用了现代g++版本,它只是工作?第二个问题,为什么询问当前职位能解决问题?

提前感谢!

现在我想知道,这是旧的g++中的一个bug吗

不,在g++中没有这方面的错误。

还是我做错了?

是的。这在你链接的答案中有解释。

…如果不调用fflush函数或文件定位函数(fseek、fsetpos或rewind),输出不能直接跟在输入后面,如果不调用文件定位函数,输入不能直接跟在输出后面,除非输入操作遇到了文件结束。

来自C标准,但通过以下方式变得相关:

对由类basic_filebuf对象控制的序列的读写限制与使用标准C库文件进行读写的限制相同。

有一个bug,但是它在你的代码中。你的程序不符合标准规定的要求。

但据我所知,这是Windows

下的限制

可能是这种情况,但更普遍的限制是在c++(和C)规范中。标准库是否有限制并不影响该库是否符合标准。任何依赖于不存在限制的代码都不符合标准。

和[I]只是幸运地使用了现代g++版本

有人可能会说你运气不好。当程序不能工作时,你发现了错误,这是一种幸运。

第二个问题,为什么询问当前职位可以解决这个问题?

我怀疑tellg是否足以使你的程序符合标准。所以,我会说它是偶然地"修复"了程序。

你可能应该用std::flush(fs);代替。

这意味着新版本不太符合标准?

不,两个版本的g++在这方面都是同样兼容的。

相关文章: