3

Im trying to create a binary file in the following way:

string buf;
...
buf += filename.length();
buf += filename;

etc. So first i give the length in binary format, but how do i convert this into a 4 byte char array, or 2 byte etc? basically i want to achieve the same functionality as this would:

int len = filename.length();
fwrite(&len, sizeof(len), 1, fp);

Which works fine, but having it in one string might be easier to process.

Edit: i dont want to use streams, nor vector, im trying to find out if its possible with strings.

4 Answers 4

4

Streams are the way to go. Not strings.

Sign up to request clarification or add additional context in comments.

10 Comments

What about stringstreams? :-)
@daniel, so this isnt possible with strings?
its not preferred. you ware working with binary data, not human-readable strings.
It's horses for courses. You wouldn't run the grand national on a Shirehorse nor would you plough a field with a Thoroughbred.
@graham.reeds, uh, my point is that if im not allowed to learn something because others says its not the best thing to do, then i will be just a blind sheep who follows others... why do i want to learn this is because i just want. i dont care how useful it will be, but it would certainly teach me something new about c++ that i didnt know yet.
|
3

Yes, it is possible to do this, because this is C++, and everything is possible in C++.

First, here is how you do it, then I'll answer the question of why you might need to do it:

std::ifstream input( "my.png", std::ios::binary );
std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(input), {});
int buffSize = buffer.size();
std::string myString(buffer.begin(), buffer.end());

In my case, I was using a framework where the HTTP Client only supported a string for post message body, but I needed to post raw binary of a file to the service I was using. I could either mess around with the internals of the library (bad) or introduce another unnecessary dependency for a simple file post (also not so good).

But since strings can hold this data, I was able to read the file, copy it to a string and then upload.

This is an unfortunate situation to be in, either way, but in some cases it is helpful to be able to do. Usually you would want to do something different. This isn't the clearest for someone else to read, and you will have some performance penalties from the copy, but it works; and it helps to understand the internals of why it works. std::string saves the data contiguously internally in binary format, like vector does, and can be initialized from iterators in the vector.

unsigned char is one byte long, so it is like a byte value. The string copies the bytes into itself, so you end up with the exact data.

Comments

2

Use a vector for holding the data, or write it straight to the file (via streams)

Comments

2

simply use std:vector<unsigned char> and use a istream or ostream iterator to read/write data to/from the vector. For instance to read from a file you can do:

vector<unsigned char> binary_buffer;

ifstream in_file("my_binary_file.bin", ios_base::binary | ios_base::in);
istream_iterator<unsigned char> end_of_file;
istream_iterator<unsigned char> in_file_iter(in_file);

while (in_file_iter != end_of_file)
{
    binary_buffer.push_back(*in_file_iter++);
}

Output would be even simpler:

ofstream out_file("another_binary_file.bin", ios_base::binary | ios_base::out);
ostream_iterator<unsigned char> binary_output(out_file);
copy(binary_buffer.begin(), binary_buffer.end(), binary_output);

4 Comments

std::string is binary save and can be used as an byte array.
@Ludger: using std::string implies (at least at first sight) that you want to treat such data as a string of text, while with an std::vector<unsigned char> it's clear that it's just a binary blob.
@matteo, just wondering, why does string allow binary data at all if it should never be used that way?
"Allowing binary data" is just an effect of the fact that text strings are just a particular type of binary data. The difference between std::string and std::vector<unsigned char> is not really in how the data is stored (both can store any character in a contiguous array), but in how it is going to be used, and thus in the methods they provide (std::string have methods used commonly on strings, conversions to/from C strings, ...).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.