如何解决如何将二进制文件转换为size_t?
我试图理解指针和二进制,但是我被困住了。我想将包含5个水果的列表写到二进制文件中。因此,我首先尝试编写(size_t)5,然后为每个水果块编写大小,然后是字符串本身。 这是我到目前为止所得到的:
// Write
vector<string> fruit_list = {"Apple","Pear","Banana","Cherry","Melon"};
ofstream fruits_out;
fruits_out.open("fruits.bin",std::ios::binary | std::ios::out);
size_t fruit_total = fruit_list.size();
fruits_out.write((char*)&fruit_total,sizeof(fruit_total));
for (const string& fruit : fruit_list){
size_t fruit_size = fruit.size();
fruits_out.write((char*)&fruit_size,sizeof(fruit_size));
fruits_out.write(&fruit.c_str()[0],fruit_size);
}
fruits_out.close();
// Read
ifstream fruits_in;
fruits_in.open ("fruits.bin",std::ios::binary | std::ios::in);
char *buffer = new char;
fruits_in.read((char*)&buffer,sizeof(size_t));
cout << *buffer << endl;
我什至无法读取第一个值。 无论如何,请帮我,我已经坚持了很长时间。
解决方法
您的编写代码很好(减少了对错误的处理,并且当&c_str()[0]
本身就足够时,无需使用c_str()
)。
但是,您的阅读代码全错了。不仅要分配大小仅为1个字节的buffer
,而且还要尝试向其中读取sizeof(size_t)
个字节。但是更糟糕的是,您正在读buffer
变量所在的堆栈空间,而不是读到buffer
所指向的动态内存!
就像编写代码通过指向size_t
的指针传递ostream::write()
一样,您也可以通过指向size_t
的指针传递istream::read()
。
尝试更多类似的方法:
std::ostream& writeSizeT(std::ostream &out,size_t value)
{
out.write(reinterpret_cast<char*>(&value),sizeof(value));
/* alternatively:
uint64_t temp = htobe64(value); // or equivalent...
out.write(reinterpret_cast<char*>(&temp),sizeof(temp));
*/
return out;
}
std::ostream& writeString(std::ostream &out,const std::string &value)
{
size_t size = value.size();
if ((writeSizeT(out,size)) && (size > 0)) {
out.write(value.c_str(),size);
}
return out;
}
std::ostream& writeFruitList(std::ostream &out,const std::vector<std::string> &list)
{
if (writeSizeT(out,list.size())) {
for (const std::string &fruit : list){
if (!writeString(out,fruit)) {
break;
}
}
}
return out;
}
std::vector<std::string> fruit_list = {"Apple","Pear","Banana","Cherry","Melon"};
std::ofstream fruits_out("fruits.bin",std::ios::binary);
writeFruitList(fruits_out,fruit_list);
fruits_out.close();
std::istream& readSizeT(std::istream &in,size_t &value)
{
in.read(reinterpret_cast<char*>(&value),sizeof(value));
/* alternatively:
uint64_t temp;
if (in.read(reinterpret_cast<char*>(&temp),sizeof(temp))) {
temp = be64toh(temp); // or equivalent...
value = static_cast<size_t>(temp);
}
*/
return in;
}
std::istream& readString(std::istream &in,std::string &value)
{
value.clear();
size_t size;
if ((readSizeT(in,size)) && (size > 0)) {
value.resize(size);
in.read(&value[0]/*or: value.data()*/,size);
}
return in;
}
std::istream& readFruitList(std::istream &in,std::vector<std::string> &list)
{
list.clear();
size_t size;
if (readSizeT(in,size)) {
list.reserve(size);
std::string fruit;
for (size_t i = 0; (i < size) && (readString(in,fruit)); ++i){
list.push_back(std::move(fruit));
}
}
return in;
}
std::vector<std::string> fruit_list;
std::ifstream fruits_in("fruits.bin",std::ios::binary);
readFruitList(fruits_in,fruit_list);
fruits_out.close();
for (const auto &fruit: fruit_list) {
std::cout << fruit << std::endl;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。