格式化输入需要分隔符,以便它知道何时停止读取特定值。即使您以二进制模式打开文件,您所编写的本质上也是一个没有分隔符的文本文件,因此您无法读回它。
如果您必须有一个二进制文件,那么这是使用您的结构读/写一个二进制文件的方法:
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
#include <vector>
const char* SettingsFilePath = "settings.bin";
struct Setting
{
int SettingID;
int SettingINTValue;
double SettingDOUBLEValue;
char SettingCHARValue;
std::string SettingSTRINGValue;
std::string SettingName;
Setting()
: SettingID(0)
, SettingINTValue(0)
, SettingDOUBLEValue(0)
, SettingCHARValue(0)
{
}
void Write(std::fstream& out)
{
out.write(reinterpret_cast<const char*>(&SettingID), sizeof(SettingID));
out.write(reinterpret_cast<const char*>(&SettingINTValue), sizeof(SettingINTValue));
out.write(reinterpret_cast<const char*>(&SettingDOUBLEValue), sizeof(SettingDOUBLEValue));
out.write(reinterpret_cast<const char*>(&SettingCHARValue), sizeof(SettingCHARValue));
size_t str_size = SettingSTRINGValue.size();
out.write(reinterpret_cast<const char*>(&str_size), sizeof(str_size));
out.write(SettingSTRINGValue.c_str(), SettingSTRINGValue.size());
str_size = SettingName.size();
out.write(reinterpret_cast<const char*>(&str_size), sizeof(str_size));
out.write(SettingName.c_str(), SettingName.size());
}
void Read(std::fstream& in)
{
in.read(reinterpret_cast<char*>(&SettingID), sizeof(SettingID));
in.read(reinterpret_cast<char*>(&SettingINTValue), sizeof(SettingINTValue));
in.read(reinterpret_cast<char*>(&SettingDOUBLEValue), sizeof(SettingDOUBLEValue));
in.read(reinterpret_cast<char*>(&SettingCHARValue), sizeof(SettingCHARValue));
size_t str_size;
std::vector<char> str_data;
in.read(reinterpret_cast<char*>(&str_size), sizeof(str_size));
str_data.resize(str_size);
in.read(&str_data[0], str_size);
SettingSTRINGValue.assign(str_data.begin(), str_data.end());
in.read(reinterpret_cast<char*>(&str_size), sizeof(str_size));
str_data.resize(str_size);
in.read(&str_data[0], str_size);
SettingName.assign(str_data.begin(), str_data.end());
}
void Print(const std::string& title)
{
std::cout << title << "\n";
std::cout << std::string(title.size(), '-') << "\n";
const size_t w = 22;
std::cout << std::setw(w) << std::right << "SettingID : " << SettingID << "\n";
std::cout << std::setw(w) << std::right << "SettingINTValue : " << SettingINTValue << "\n";
std::cout << std::setw(w) << std::right << "SettingDOUBLEValue : " << SettingDOUBLEValue << "\n";
std::cout << std::setw(w) << std::right << "SettingCHARValue : " << SettingCHARValue << "\n";
std::cout << std::setw(w) << std::right << "SettingSTRINGValue : " << SettingSTRINGValue << "\n";
std::cout << std::setw(w) << std::right << "SettingName : " << SettingName << "\n";
std::cout << "\n";
}
};
int main()
{
{
Setting s;
s.Print("Default before Write");
s.SettingID = 1;
s.SettingINTValue = 2;
s.SettingDOUBLEValue = 3.5;
s.SettingCHARValue = 'Z';
s.SettingSTRINGValue = "Blah Blah";
s.SettingName = "Some Settings";
std::fstream f(SettingsFilePath, std::ios::out | std::ios::binary);
s.Write(f);
s.Print("Values written to file");
}
{
Setting s;
s.Print("Default before read");
std::fstream f(SettingsFilePath, std::ios::in | std::ios::binary);
s.Read(f);
s.Print("Values after read");
}
return EXIT_SUCCESS;
}