1

I am trying to write one byte to a file in C++. When I save it, is is 8 byte large, instead of 1 byte. How can I save exactly one byte?

ofstream binFile("compressed.bin", ios::out | ios::binary); bitset<8> a("10010010"); binFile << a; 

Output of ls -la:

.rw-r--r-- name staff 8 B Sat Dec 4 23:26:18 2021  compressed.bin 

How can I small it down to one byte?

3
  • I think the posted duplicate Why is std::bitset<8> 4 bytes big? explains the problem, but does not answer the question asked here. Voting to reopen. Commented Dec 4, 2021 at 23:04
  • Did you look at the contents of the file? Seeing what was output can be more informative than looking at just how much was output. (A hex editor can be useful when you expect non-text data in the file. Or for a file this small, you could create another program that reads each byte from compressed.bin, converts to an integer, and streams that to the screen (don't forget a space between numbers). Commented Dec 4, 2021 at 23:31
  • Oh.. and if the "another program" I mentioned reports that all (or most) of the integer values are in the range 32-126, consider converting to char instead, as that is the range of printable characters. Commented Dec 7, 2021 at 5:35

2 Answers 2

3

operator << is designed for formatted output.

When writing strict binary, you should focus on member functions put (for one byte) or write (for a variable number of bytes).

This will write your bitset as a single byte.

binFile.put( a.to_ulong() ); 
Sign up to request clarification or add additional context in comments.

Comments

-2

I'm not sure what class bitset<size_t> is, but it seems to be creating a uint64_t underneath. Maybe the template parameter is for number of bytes instead of bits?

I can achieve a single byte binary file with

std::ofstream binFile("onebyte.bin", std::ios::out | std::ios::binary); uint8_t aByte = 0x77; // this is w in ASCII. Easy to see in a bin file binFile << aByte; 

Perhaps you need to cast bitset to a uint8_t?

5 Comments

"Maybe the template parameter is for number of bytes instead of bits?" -- No.
"Perhaps you need to cast bitset to a uint8_t?" -- results in error: invalid cast from type 'std::bitset<8>' to type 'uint8_t'.
When you don't know what the subject of a question is, you should probably test your theory before answering (which is a good idea in any case). Even better, also look up the documentation.
Ah, ok. You're using the STL bitset. So if you read the constructor here: en.cppreference.com/w/cpp/utility/bitset/bitset You'll see it constructs a 64 (or 32byte depending on c++ version) if the size is less than 64. So you want to either use put with .en.cppreference.com/w/cpp/utility/bitset/to_ulong as Drew Dormann described above, or static_cast that return from that to a uint8_t and use the stream operator. I think Drew gave a good explanation for why .put() is more appropriate
"You'll see it constructs a 64 (or 32byte depending on c++ version) if the size is less than 64." -- I see no such thing in the documentation. The only occurrence of 32 (and of 64) on that page refers to the size of the parameter to a constructor, not to the size of the constructed object. That part of the documentation says that if you construct a std::bitset<90> from a 64-bit unsigned long long, then the low 64 bits are set from the unsigned long long and the remaining 26 bits are initialized to zeroes.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.