Writing bitstrings to a binary file in C++ - c++

I am working on a compressor which compresses text files using Huffman coding in C++. After I perform the encoding, I get a bitstring(assume arbitrary length or say length = 2611) which represents the encoded file. Now, I want to write this bitstring to a binary file. How can I do this? Can bitset be of some use?
I am aware of the fact that the file size has to be integer number of bytes, so I will pad the bitstring to make the length a multiple of 8.
I saw some other related questions but they used pre-determined size bitset. In my case the bitstring can be quite long.
Thanks in advance!
PS: I would only want to write to a binary file, not a text file, otherwise it will make no sense to encode.
EDIT1: take for example the bitstring - "10010101010010101010101011101100001001000101011110110101001010101001001010110101"
Length is 80 that wld mean 10 bytes. I want to write these 10bytes into a binary file. How can I do this beginning with the bitstring?

Does this example respond to your question, in terms of writing bistsets into a file?
As far as i know, you can write bitset directly to a file
#include <iostream>
#include <string>
#include <bitset>
#include <fstream>
int main ()
{
std::ofstream ofs ("testfile", std::ofstream::out);
std::bitset<16> foo; // not intialized
std::bitset<16> bar (0xfa2);
std::bitset<16> baz (std::string("0101111001"));
std::cout << "foo: " << foo << '\n';
std::cout << "bar: " << bar << '\n';
std::cout << "baz: " << baz << '\n';
ofs << "foo: " << foo << '\n';
ofs << "bar: " << bar << '\n';
ofs << "baz: " << baz << '\n';
ofs.close();
return 0;
}
This code would output in the console:
foo: 0000000000000000
bar: 0000111110100010
baz: 0000000101111001
and the same output in the file testFile

Funnily enough I'm doing the exact same thing.
After you check a character in your Huffman codes and take bitstring from it you would want to do something like
ofstream encoder(outputFilePath, ios::out | ios::binary | ios::app);
This ofstream has the proper flag to write binary strings.
after that you'd just have to write the output to a file.

Related

Why does boost::basic_array_source give other values than what I have stored with boost::iostreams::back_insert_device?

I am trying to use functions of a library that reads and writes from/to streams. To adapt my data to that library, I wanted to use boost::iostreams from boost 1.77.0. Still, a first very simple example does not work as expected. Why?
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/stream.hpp>
#include <iostream>
int main(int, char*[])
{
// Create container
std::vector<char> bytes;
// Set up stream to write three chars to container
boost::iostreams::back_insert_device<std::vector<char>> inserter =
boost::iostreams::back_inserter(bytes);
boost::iostreams::stream stream(inserter);
// Write chars
stream << 1;
stream << 2;
stream << 3;
stream.close();
// Check container
for (char entry : bytes)
{
std::cout << "Entry: " << entry << std::endl;
}
std::cout << "There are " << bytes.size() << " bytes." << std::endl;
// Set up stream to read chars from container
boost::iostreams::basic_array_source<char> source(bytes.data(), bytes.size());
boost::iostreams::stream stream2(source);
// Read chars from container
while (!stream2.eof())
{
std::cout << "Read entry " << stream2.get() << std::endl;
}
return 0;
}
The output is:
Entry: 1
Entry: 2
Entry: 3
There are 3 bytes.
Read entry 49
Read entry 50
Read entry 51
Read entry -1
Why does it read 49, 50 and 51 instead of 1, 2 and 3? The -1 doesn't surprise me that much, it might denote the end of the container. Am I using the classes in a wrong way?
It works correct to me, but not in the intuitive way though. You are putting integers 1 2 and 3 into the vector of chars via stream, so they land there as their ASCII codes, 49, 50 and 51 respectively. In the initial loop you are actually printing characters, not their integer representations, thus. I suggest you should try std::cout << "Entry: " << +entry << std::endl; (note the + sign) and it will become clear.

How do I take a character pointer of 20 characters to output the contents plus the extra whitespace?

This is my first C++ related question and I'm new to character pointers and their usage. I think I've got it down but for an assignment the required output for this program is
So each first and last name is a character pointer of 20 characters (I could probably size it down but whatever) and when I output it now it looks like
cout << stu[i]->first << " " << stu[i]->last << " " << (float)stu[i]->mean << endl; and outputs the same thing as above but with a single space between each piece of data. How would I get it to print out the whitespace of the rest of the char pointer so it creates nice neat columns?
Thanks!
There is no magic whitespace in memory a char* points to. If you want to align your output you could use std::setw():
#include <iostream>
#include <iomanip>
int main()
{
char const *foo{ "Jamie" };
char const *bar{ "Reynolds" };
std::cout << std::setw(10) << foo << std::setw(10) << bar << '\n';
}

c++ string concatenation second time

I am a newbie, writing a c++ code to open and read from multiple files and then dump part of the data into other files.
I want to generate file names in a for loop.
But I can't concatenate string(numbering of file) and string literal(a file extension). The same line of code works at the very beginning of the program, but not at the later part.
int main(int argc, char *argv[])
{
std::cout << std::string("9") + ".dat" << std::endl;
// many more lines
dump = 1;
if (dump == 1){
for (int ilevel=std::max(levelmin,lmin); ilevel < lmax + 1; ilevel++){
std::cout << std::string("9") + ".dat" << std::endl; // crashes here!
std::ofstream fout (std::string("9") + ".dat", std::ios::out | std::ios::binary);
std::cout << grid[ilevel].cube[0] << std::endl;
fout.write ((char*)&grid[ilevel].cube[0], grid[ilevel].cube.size() * sizeof(grid[ilevel].cube[0]));
fout.close();
}
}
...
}
If I put std::cout << std::string("9") + ".dat" << std::endl; at the beginning, it works and prints "9.dat".
but in the later loop, segmentation fault.
In between I call a function that uses stringstream to pad leading zeros to an integer. The function looks:
std::string int2str(const int n, const int m){
std::stringstream ss;
ss << std::setfill('0') << std::setw(m) << n;
std::string s2(ss.str());
ss.clear();
return s2;
}
I don't have a clear understanding about string and stringstream in c++.
But out of many things in my program, this function is the only thing I can think of being relevant. Other parts of codes does not deal with strings. It's mostly array manipulation code.
I've also tried std::string("9") + std::string(".dat")
but had no luck.
What is wrong?
Is there a specific reason why you're using std::string("9") rather than just "9"?
Where does the 9 come from? If its generated as part of a loop or a returned value from a function you can either place the variable itself to be concatenated, or the function that returns it, so:
std::cout << iFileNumber + ".dat" << std::endl;
or
std::cout << fileNumberGenerator() + ".dat" << std::endl;
For the hardcoded examples you've provided, I personally can't see the need for anything other than
std::cout << 9 + ".dat" << endl;
but that could easily just be lack of experience on my part.
For the sake of printing to the command line, its also worth nothing that this is equally acceptable syntax (assuming you're not already aware):
std::cout << 9 << ".dat" << endl;

Save Int Data into Text File in C++

I working on saving Data into text file and compare it with another text file. Below is the code I worked on:
ofstream outfile;
outfile.open("Data",ios::out | ios :: binary);
for(x=0; x<100; x++)
{
printf("data- %x\n", *(((int*)pImagePool)+x));
int data = *(((int*)pImagePool)+x);
//outfile<<(reinterpret_cast<int *>(data))<<endl;
outfile<<(int *)data<<endl;
}
The result from printf is 24011800 and result read from text file is 0x24011800
Why there is 0x appeared? Do we able to remove it?
What is the difference between reinterpret_cast<int *> & (int *) but both giving the same result?
It's because you cast it as a pointer, so the output will be a pointer.
Since data is a normal value variable, just write it as usual:
outfile << data << '\n';
I also recommend you stop using printf when programming C++, there no reason to use it. Instead output using std::cout:
std::cout << "data- " << *(((int*)pImagePool)+x) << '\n';
Or if you want hexadecimal output
std::cout << "data- " << std::hex << *(((int*)pImagePool)+x) << '\n';
"%x" is a specifier for a hexadecimal number. Check this table: http://www.cplusplus.com/reference/cstdio/printf/
Use "%d" to output a decimal.
EDIT: About the casting, see this:
Reinterpret_cast vs. C-style cast
This is a very simple example using the ofstream f. The most complicated part are the parameters passed to the open, specifically std::ios::out which specifies the file direction. You could also use std::ios:in for reading from a file along with cin.
// ex5.cpp
#include <string>
#include <iostream>
#include <fstream>
#include "hr_time.hpp"
#include >ios>
int main(int argc, char * argv[])
{
CStopWatch sw;
sw.startTimer() ;
std::ofstream f;
f.open("test.txt",std::ios::out ) ;
for (int i=0;i<100000;i++)
{
f << "A very long string that is number " << i << std::endl;
}
f.close() ;
sw.stopTimer() ;
std::cout << "This took " << sw.getElapsedTime() << " seconds" << std::endl;
return 0;
}

"Roll-Back" or Undo Any Manipulators Applied To A Stream Without Knowing What The Manipulators Were [duplicate]

This question already has answers here:
Restore the state of std::cout after manipulating it
(9 answers)
Closed 4 years ago.
If I apply an arbitrary number of manipulators to a stream, is there a way to undo the application of those manipulators in a generic way?
For example, consider the following:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
cout << "Hello" << hex << 42 << "\n";
// now i want to "roll-back" cout to whatever state it was in
// before the code above, *without* having to know
// what modifiers I added to it
// ... MAGIC HAPPENS! ...
cout << "This should not be in hex: " << 42 << "\n";
}
Suppose I want to add code at MAGIC HAPPENS that will revert the state of the stream manipulators to whatever it was before I did cout << hex. But I don't know what manipulators I added. How can I accomplish this?
In other words, I'd like to be able to write something like this (psudocode/fantasy code):
std::something old_state = cout.current_manip_state();
cout << hex;
cout.restore_manip_state(old_state);
Is this possible?
EDIT:
In case you're curious, I'm interested in doing this in a custom operator<<() I'm writing for a complex type. The type is a kind of discriminated union, and different value types will have different manips applied to the stream.
EDIT2:
Restriction: I cannot use Boost or any other 3rd party libraries. Solution must be in standard C++.
Yes.
You can save the state and restore it:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
std::ios state(NULL);
state.copyfmt(std::cout);
cout << "Hello" << hex << 42 << "\n";
// now i want to "roll-back" cout to whatever state it was in
// before the code above, *without* having to know what modifiers I added to it
// ... MAGIC HAPPENS! ...
std::cout.copyfmt(state);
cout << "This should not be in hex: " << 42 << "\n";
}
If you want to get back to the default state you don't even need to save the state you can extract it from a temporary object.
std::cout.copyfmt(std::ios(NULL));
The standard manipulators all manipulate a stream's format flags, precision and width settings. The width setting is reset by most formatted output operations anyway. These can all be retrieved like this:
std::ios_base::fmtflags saveflags = std::cout.flags();
std::streamsize prec = std::cout.precision();
std::streamsize width = std::cout.width();
and restored:
std::cout.flags( saveflags );
std::cout.precision( prec );
std::cout.width( width );
Turning this into an RAII class is an exercise for the reader...
Saving and restoring state is not exception-safe. I would propose to shuffle everything into a stringstream, and finally you put that on the real stream (which has never changed its flags at all).
#include <iostream>
#include <iomanip>
#include <sstream>
int main()
{
std::ostringstream out;
out << "Hello" << std::hex << 42 << "\n";
std::cout << out.str();
// no magic necessary!
std::cout << "This should not be in hex: " << 42 << "\n";
}
Of course this is a little less performant. The perfect solutions depends on your specific needs.
Boost IO State saver might be of help.
http://www.boost.org/doc/libs/1_40_0/libs/io/doc/ios_state.html
I know that is an old question, but for future generations:
You can also write a simple state saver yourself (it will certainly help you avoid leaving the state changed). Just use the solution suggested by #loki and run it from the constructor/destructor of an object (in short: RAII) along these lines:
class stateSaver
{
public:
stateSaver(ostream& os): stream_(os), state_(nullptr) { state_.copyfmt(os); }
~stateSaver() { stream_.copyfmt(state_); }
private:
std::ios state_;
ostream& stream_;
};
Then, you will use it like this:
void myFunc() {
stateSaver state(cout);
cout << hex << 42 << endl; // will be in hex
}
int main() {
cout << 42 << endl; // will be in dec
myFunc();
cout << 42 << endl; // will also be in dec
}