简体   繁体   中英

How do I convert a binary file to size_t?

I'm trying to understand pointers and binary, but I'm stuck. I want to write a list containing 5 pieces of fruit to a binary file. So firstly I try to write (size_t) 5, then for each fruit piece the size of it and then the string itself. This is what I got so far:

// 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;

I can't even read the first value. Please help me no this matter, I'm stuck on it for ages.

Your writing code is fine (minus a lack of error handling, and there is no need to use &c_str()[0] when c_str() by itself will suffice).

However, your reading code is all wrong. Not only are you allocating a buffer that is only 1 byte in size and then you try to read sizeof(size_t) number of bytes into it. But worse, you are reading into stack space where the buffer variable is located, not into the dynamic memory that you allocated which buffer is pointing at!

Just like the writing code is passing a size_t by pointer to ostream::write() , you can also pass a size_t by pointer to istream::read() as well.

Try something more like this:

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM