Alternative to fwrite in C++ other than fstream and ostream

Pages: 12
Hello guys,

writing binary files with fstream is really annoying. I noticed that it formats the numbers and modifies their precision, and it's twice slower compared to fwrite. I find fwrite reasonable because it simply copies data from memory (pointer) to a file. Is there a C++ alternative to fwrite that is fast and copies memory without messing the binary data? is what I'm thinking about fstream wrong or I'm probably misusing it?

Thank you,
Sam
You can use unformatted output methods from ostream like write and put.
http://www.cplusplus.com/reference/iostream/ostream/
Thanks for your fast answer.

Actually fstream::write is what I was talking about. It edited the precision of the numbers in the my array, unlike fwrite. And I noticed that fstream::precision(int n) affects the written unformatted numbers which was a stunning fact!!!!! I wanted a pure copy from memory to disk.

Have I done something wrong for that to happen?
I'd say nothing wrong with using fwrite for pure copy from memory to disk.

EDIT: you can encapsulate it with a class though
Last edited on
How are you writing? write doesn't write numbers at all, it's for raw data.
Maybe you are using fwrite improperly

PS: C++ streams look a lot like stdio wrappers ...
Thank you guys for your answers!

@coder777: I'm using fwrite right now for my apps. But I wonder whether there's a good competitive C++ method!!!! I hate using pure C commands! it just feels not right with me :-).

@Bazzy: I'm using it to write an array of numbers in binary format. So for example:

1
2
3
4
5
6
7
8

double *array = new double[1000];

//fill the array

fstream output("blabla.bin",ios::out | ios::bin);
output.write(array,sizeof(double)*1000);


And with this method the precision of the numbers can be changed using fstream::precition(int n)!! which is extremely strange!!!! anything wrong with the idea?
Because you shouldn't write numbers like that. That's what I meant when I said "you are using fwrite improperly".
The code above shouldn't even compile on C++.
You can't just write values like that: computer with different endianness will give different results.
You need to convert the values into a known representation, much of the internal representation of basic types is implementation defined.

By the way, I tried the following code:
1
2
3
4
5
6
7
8
double *array = new double[2];
array[0] = 1;
array[1] = 2.5;
fstream output("blabla.bin",ios::out | ios::binary);
output.write((char*)array,sizeof(double)*2);
output.put('!');
output.precision(5);
output.write((char*)array,sizeof(double)*2);
And the output was the same to the left and to the right of the '!'

Which compiler are you using?
Thanks for your efforts man :-)

Ah! I'm sorry! I omitted the cast of the array! I do the casting in my program actually... I just thought it's obvious.

I'm using g++. You probably have gotten the same output because you're not "filling" the double precision digits. I do Fourier transforms in my program, and the results are so nasty and fill the whole 64 bits with digits. The precision doesn't matter actually in your example, because in binary representation your first element 1 is 1, and 2.5 is 10.1, and even if you use the IEEE754 to convert them to doubles they're still so simple. Both are so short that precision 5 doesn't even think about them.

Try some more complicated numbers, and you'll see how differences will show up!

EDIT: And about the endiannes it doesn't matter so much because I'm in the university and the analysis is done only on Intel computers and on the same computer.
Last edited on
With these numbers the result is the same
1
2
array[0] = 3.1415926535897932384626;
array[1] = 2.7182818284590452353602;

The point is, precision does not affect raw output.
( anyway, how could the stream know that you are passing a casted double ? )
Which g++ version? I'm using g++ 4.5.2 on Ubuntu 10.10 x86_64
Last edited on
I'm using 4.4.5 on Ubuntu like yours.

I'm surprised... actually you're right! it doesn't make sense at all, but it was the case! and I don't know how it happened. This was like 1 month ago, and since then I'm using fwrite and saving myself the headache! So I wanted to make sure it was my fault!

I guess I'm gonna try it again with that!! Thank you for your time. :-)

So in conclusion, C++ uses only ofstream and fstream for file output, there's not another way. It's surprising because I saw a comparison between ofstream and fwrite on a website and they stated that fstream is twice slower than fwrite!!!! why would that be the case??
Unformatted output should take the same time using C++ streams and C stdio.
Some people claim that C is faster than C++ but most of the time it's not true.
Thanks for everything man :-)
closed account (zwA4jE8b)
I am unfamiliar with binary writing an am playing with the example you gave Bazzy.

How would I read the .bin file back in to get the numbers?
Do I open it in binary mode? and what datatype do I read it into?

1
2
3
fstream input("binwrite.bin", ios::in);
char* in = new char;
input.read(in, sizeof(double)*2);
If you want to read as it is into a double and hope that everything works fine you can do it like this:
1
2
3
ifstream input("binwrite.bin", ios::in | ios::binary);
double d;
input.read( (char*)&d, sizeof(double) );


Note: This is bad for the reason I gave above
closed account (zwA4jE8b)
What then is recommended for getting data out of binary files? What way is not 'bad'?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void main()
{
	char *out = new char[1];
	*out = 'A';
	char *in = new char;
	fstream output("binwrite.bin", ios::out | ios::binary);
	output.write(out,sizeof(char));
	output.close();

	fstream input("binwrite.bin", ios::in);
	input.read(in, sizeof(char));
	cout << *in;

	cin.get();
}


I wrote this to practice and I get my A back out. So it seems to work.
Chars are perfectly fine to work with. It's really only a problem when you work with floating point numbers. You have to set precision if you just straight use << >> and it won't be cross architecture.
Reading/writing char arrays like that is fine. Reading/writing directly as binary other types is bad.
If you want to read/write a single character you should call get/put.
( sizeof(char) is always 1 )
closed account (zwA4jE8b)
oh ok. cool. I will have to practice more with this type of file I/O.

Do you have any recommended tutorial or articles. Is writing floating point numbers to files always difficult?
Difficult, not really. But I believe Duous has a good post on big endian little endian stuff. And the way they are stored is different on different computers. You can look at beej's guide (on socket programming) for some simple encoding.
Last edited on
Writing formatted floats is easy ( just use << operator )
Writing in binary anything which is not already stored as characters is not as trivial.
If you want to get more info on binary I/O in general search for "serialization" or "marshalling".
If you want C++ stream specific info read the reference ( http://www.cplusplus.com/reference/iostream/ostream/ )
Pages: 12