Al Berger
Al Berger

Reputation: 1068

std::basic_fstream<unsigned char> doesn't work on Linux

I'm getting a failure on Linux when calling the read() function on basic_fstream<unsigned char> stream:

basic_fstream<unsigned char> fs;
basic_string<unsigned char> buf(1000, '\0');
fs.open( "/tmp/file.txt", ios::in | ios::binary);
fs.read( &buf[0], 1000);

I traced where it throws: in function __check_facet(const _Facet* __f) it throws __throw_bad_cast() because __f is NULL. The __check_facet() in turn is called from underflow(), with _M_codecvt as the parameter (which is NULL and causes the failure).

The system's locale is UTF8, the code is compiled with --std=c++14. On Windows this works OK.

Can it be corrected somehow?

Upvotes: 1

Views: 158

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 597610

The standard library is not required to provide facets or locales for unsigned char. The standard streams are designed only with char (and wchar_t) in mind.

I would suggest using the standard std::ifstream instead. You can read binary data with it, and store it into an unsigned char buffer. You should consider using the standard std::vector container instead of std::basic_string for that buffer.

Try this instead:

ifstream fs("/tmp/file.txt", ios::binary);
vector<unsigned char> buf(1000);
fs.read( reinterpret_cast<char*>(&buf[0]), 1000);

This will work equally on all platforms.

Upvotes: 1

Related Questions