std :: basic_ofstream <std :: uint8_t> ошибка записи в __check_facet () - PullRequest
0 голосов
/ 31 марта 2019

Я пытаюсь записать некоторые двоичные данные в файл, используя std::basic_ofstream<std::uint8_t>, но он выдает bad_cast в __check_facet (). Я предполагаю, что каким-то образом мне нужно imbue() поток с локалью, которая имеет std::codecvt<std::uint8_t, char, std::mbstate_t>, но я действительно не знаю, как это сделать. Моя мотивация заключается в том, что я хотел бы дифференцировать операторы потока, которые записывают двоичные данные (версия std :: uint8_t), от операторов, которые записывают текстовые данные (char).

Сбой, когда write вызывает __check_facet() и имеет нулевой указатель, поэтому выдает bad_cast.

(gdb) l
45    template<typename _Facet>
46      inline const _Facet&
47      __check_facet(const _Facet* __f)
48      {
49        if (!__f)
50           __throw_bad_cast();
51        return *__f;
52      }

#0  std::__check_facet<std::codecvt<unsigned char, char, __mbstate_t> > (__f=0x0) at /usr/include/c++/7/bits/basic_ios.h:50
#1  0x000055555555a1c0 in std::basic_filebuf<unsigned char, std::char_traits<unsigned char> >::xsputn (this=0x7fffffffdc38, __s=0x7fffffffdc2f "*X\311uUUU", __n=1)
    at /usr/include/c++/7/bits/fstream.tcc:731
#2  0x0000555555557301 in std::basic_streambuf<unsigned char, std::char_traits<unsigned char> >::sputn (this=0x7fffffffdc38, __s=0x7fffffffdc2f "*X\311uUUU", __n=1) at /usr/include/c++/7/streambuf:451
#3  0x000055555555693c in std::basic_ostream<unsigned char, std::char_traits<unsigned char> >::_M_write (this=0x7fffffffdc30, __s=0x7fffffffdc2f "*X\311uUUU", __n=1) at /usr/include/c++/7/ostream:313
#4  0x00005555555560b0 in std::basic_ostream<unsigned char, std::char_traits<unsigned char> >::write (this=0x7fffffffdc30, __s=0x7fffffffdc2f "*X\311uUUU", __n=1)
    at /usr/include/c++/7/bits/ostream.tcc:196
#5  0x0000555555555cb1 in main () at test.cpp:7
#include <fstream>

int main()
{
    std::basic_ofstream<std::uint8_t> ofs("test.bin", std::ios_base::out | std::ios_base::binary);
    std::uint8_t x = 42;
    ofs.write(&x, 1);
    ofs.close();
}

Проблема возникает только в Linux с g ++ (в настоящее время используется 7.3.0), в Windows с msvc работает нормально.

Edit:

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

#include <fstream>

struct A
{
    std::uint32_t number = 10;
};

std::ofstream& operator<<(std::ofstream& s, const A& a)
{
    s << "The number is: " << a.number;
    return s;
}

std::basic_ofstream<std::uint8_t>& operator<<(std::basic_ofstream<std::uint8_t>& s, const A& a)
{
    s.write(reinterpret_cast<const std::uint8_t*>(&a.number), 4);
    return s;
}

int main()
{
    A a;
    std::ofstream textFile("test.txt");
    textFile << a;
    textFile.close();

    std::basic_ofstream<std::uint8_t> binaryFile("test.bin", std::ios_base::out | std::ios_base::binary);
    binaryFile << a;
    binaryFile.close();
}

Спасибо!

...