18

I was making a program that read binary files. So, I read the individual bytes into unsigned chars (actually reading the data as chars and casting them to unsigned chars for each character). Now I have to write back the unsigned chars to the binary file.

The problem is that now I am forced to write individual bytes after casting them to chars (because write() for binary files expects char* buffer). So, now i have to do the following:

for(int x=0; x<data_size; x++)
{
    ch=(char)data[x];
    outfile.write(&ch,1);
}

Is there any way to get around this thing so that the amount of I/O operations are reduced in case of reading and writing?

1
  • Don't write one byte at a time, but larger blocks (say 64kiB). Same for reading, for that matter. Commented Aug 9, 2011 at 12:14

3 Answers 3

29

You can do the casting on a pointer...

outfile.write((char *)&data[0], data_size);

the same can be done for reading (i.e. just pass a pointer to the first element of an array of unsigned char casting it to a pointer to char).

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

5 Comments

I would like an explicit reinterpret_cast better
@Kerrek: The question stated that outfile.write was expecting a char*
I'm tempted to say, don't use either. If it's just temporary data, fine, but if you write the data like this, some time in the future, you won't be able to read it.
@James Kanze: Are you advocating to save every pixel of an RGB image with an xml node? :-)
@6502 Where did I say anything about XML? I am advocating saving data in a known and defined format, so that you can reread it later. (Most image files have a defined format which you have to respect.)
6

The type of outfile is ofstream, right? ofstream is a typedef for,

typedef std::basic_ofstream<char, std::char_traits<char> > ofstream;

You need your own typedef,

typedef std::basic_ofstream<unsigned char, std::char_traits<unsigned char> > uofstream;

And then,

uofstream outfile(...);
outfile.write(data, data_size); //no need to cast

4 Comments

This is undefined behavior. An implementation is under no obligation to supply an instantiation of std::char_traits<unsigned char>, and those that do have incompatible instantiations.
@c0da It might, on a particular compiler. Or it might not. I know people who've tried to do it with VS and with g++, and got two completely different behaviors.
Regrettably, this doesn't work with gcc v.4.7.2. It creates and opens the file, but won't write any data to it.
This doesn't work with clang++ 5.0.0, although the solution looks elegant. A file gets created but the write fails and the end result is that the file's size is 0 bytes.
2

When data is of type unsigned char* or unsigned char[] and you just want to write the bits into the file do a pointer cast:

for(int x=0; x<data_size; x++)
{
outfile.write((char*)data + x, 1);
}

As casting removes the issue of one at a time writing:

outfile.write((char*)data, data_size);

And you do it all at once. Note that this outdoes the type checking and therefore is not the best solution.

Comments

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.