尝试读取二进制文件会清除文件本身
Trying to read binary file clears the file itself
我刚开始使用 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)。当我使用代码时,我唯一得到的是一个空字符串。我注意到文件的初始大小是37KB,而使用我的程序后它变成了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 KB 大小的文件上使用它会得到 0 KB 的文件。
您使用打开模式 std::ios_base::trunc
打开。从http://en.cppreference.com/w/cpp/io/ios_base/openmode可以看出
discard[s] the contents of the stream when opening
所以只需使用:
// 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;
}
不是读取文件的合适方式。想一想一个空文件会发生什么:打开它后是"good"(记住,只有当某些输入操作遇到eof 时才会设置eofbit)。然后 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?
我刚开始使用 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)。当我使用代码时,我唯一得到的是一个空字符串。我注意到文件的初始大小是37KB,而使用我的程序后它变成了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 KB 大小的文件上使用它会得到 0 KB 的文件。
您使用打开模式 std::ios_base::trunc
打开。从http://en.cppreference.com/w/cpp/io/ios_base/openmode可以看出
discard[s] the contents of the stream when opening
所以只需使用:
// 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;
}
不是读取文件的合适方式。想一想一个空文件会发生什么:打开它后是"good"(记住,只有当某些输入操作遇到eof 时才会设置eofbit)。然后 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?