尝试读取二进制文件会清除文件本身

时间:2017-05-10 08:11:11

标签: c++ file binary fstream ifstream

我刚开始使用C ++中的二进制文件,我已成功编写并读取了一个( .bin )文件。这是代码:

#include <iostream>
#include <cstring>
#include <fstream>

using namespace std;

int main()
{
    char input[100];

    strcpy(input, "This is a string");

    fstream file("example.bin", ios::binary | ios::in | ios::out | 
ios::trunc);

if(!file.is_open())
{
    cerr << "Error opening file.\n";
} else {
    for(int i = 0; i<= strlen(input); i++)
    {
        file.put(input[i]);
    }
}

file.seekg(0);
char ch;

while(file.good())
{
    file.get(ch);
    cout<<ch;
}
}

这很有效。之后,我尝试重新设计代码,只读取二进制文件。主要的变化是:将fstream改为ifstream(读取),删除部分并写入文件。代码准备好后,我找到了一个我想要阅读的文件( eof0.bin )。当我使用代码时,我唯一得到的是一个空字符串。我注意到文件的初始大小是37千字节,而在使用我的程序后它变为0.我想知道,我的程序如何清除二进制文件中的数据?

这是我用来读取文件的代码。

#include <iostream>
#include <cstring>
#include <fstream>

using namespace std;

int main()
{

ifstream file("eof0.bin", ios::binary | ios::in | ios::out | ios::trunc);

if(!file.is_open())
{
    cerr << "Error opening file.\n";
} else {
    // Nothing.
}

file.seekg(0);
char ch;

while(file.good())
{
    file.get(ch);
    cout<<ch;
}


}

所有内容都会编译,但在37千字节的文件中使用它会给我一个0千字节的文件。

1 个答案:

答案 0 :(得分:2)

您使用openmode std::ios_base::trunc打开。从http://en.cppreference.com/w/cpp/io/ios_base/openmode我们可以看到它

  

打开

时丢弃流的内容

所以只需使用:

// also dropped ios::out since you only want to read, not write
ifstream file("eof0.bin", ios::binary | ios::in);

此外,这

char ch;
while(file.good())
{
    file.get(ch);
    cout<<ch;
}

不适合读取文件。想想空文件会发生什么:打开它之后,它是“好的”(记住,eofbit仅在某些输入操作遇到eof时设置)。然后get失败,保持原样ch,从而调用未定义的行为。在输入操作后直接测试流状态:

char ch;
while (file.get(ch)) {
  // use ch
}
// optionally distinguish eof and fail cases

有关阅读文件的更多背景信息,请参阅Why is iostream::eof inside a loop condition considered wrong?