Подтвердить что ты не робот

Неожиданные результаты с двоичной записью std:: ofstream

Я новичок в С++ std:: stream, и я делаю некоторые тесты. У меня есть этот простой код:

int i = 10;
char c = 'c';
float f = 30.40f;

std::ofstream out("test.txt", std::ios::binary | std::ios::out);
if(out.is_open())
{
    out<<i<<c<<f;
    out.close();
}

Когда поток открывается как std::ios::binary, я ожидаю, что в файле test.txt будет двоичное представление i, c и f, но вместо этого у меня есть 10c30.4.

Не могли бы вы рассказать мне, что я делаю неправильно?

4b9b3361

Ответ 1

std::ios::binary promises, чтобы не делать преобразования строк в потоке (и некоторые другие небольшие поведенческие различия с текстовыми потоками).

Вы можете посмотреть

Вот пример использования Boost Spirit Karma (при условии упорядочения байтов Big-Endian):

#include <boost/spirit/include/karma.hpp>
namespace karma = boost::spirit::karma;

int main()
{
    int i = 10;
    char c = 'c';
    float f = 30.40f;

    std::ostringstream oss(std::ios::binary);
    oss << karma::format(
            karma::big_dword << karma::big_word << karma::big_bin_float, 
            i, c, f);

    for (auto ch : oss.str())
        std::cout << std::hex << "0x" << (int) (unsigned char) ch << " ";
    std::cout << "\n";
}

Отпечатает

0x0 0x0 0x0 0xa 0x0 0x63 0x41 0xf3 0x33 0x33 

Ответ 2

Чтобы писать сырые двоичные данные, вы должны использовать ostream:: write. Он не работает с выходными операторами.

Также убедитесь, что вы хотите читать из двоичного файла, чтобы не использовать оператор → , но вместо этого istream:: read.

В ссылках также приводятся примеры того, как вы можете обрабатывать двоичные данные.

Итак, для вашего примера:

int i = 10;
char c = 'c';
float f = 30.40f;

std::ofstream out("test.txt", std::ios::binary | std::ios::out);
if(out.is_open())
{
    out.write(reinterpret_cast<const char*>(&i), sizeof(i));
    out.write(&c, sizeof(c));
    out.write(reinterpret_cast<const char*>(&f), sizeof(f));
    out.close();
}