Archived

This topic is now archived and is closed to further replies.

kamrann

How do the std::fstream << >> operators work?

Recommended Posts

I''m trying to write out various bits of data to a file, say one int, then two floats, then another int, for example. I''m using ofstream (in binary mode), and I assumed I could use the << operators to do this. But when I read back in from the file, I just get junk. Can someone explain to me how exactly the << >> operators are meant to be used. Also, is there some way of creating a general fstream, so I dont have to cast everything to char* or something else whenever I want to read or write? Cheers Cameron

Share this post


Link to post
Share on other sites
The >> and << operators are only for formatted in- and output. That means that if you write an int to an fstream using <<, the output will be a text representation of that int according to the formatting settings.

If you want to do binary in- and output, you need to use the get/put member functions to read/write a single character, or use the read/write member functions to read/write blocks of data.

See this iostream reference at cplusplus.com for more information.

[edited by - JungleJim on May 2, 2002 7:05:41 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by JungleJim
The >> and << operators are only for formatted in- and output. That means that if you write an int to an fstream using <<, the output will be a text representation of that int according to the formatting settings.

If you want to do binary in- and output, you need to use the get/put member functions to read/write a single character, or use the read/write member functions to read/write blocks of data.

See this iostream reference at cplusplus.com for more information.

[edited by - JungleJim on May 2, 2002 7:05:41 AM]


Sorry to burst your bubble but that is not exactly true JungleJim.

kamrann: Your problem , as JungleJim said, is that output is written in text representation. However I am pretty sure that using get/put will not solve your problem. Insert a space between each int or float as you write them to the file. Then as you read them back in, do a filestream.ignore(1) to ignore the spaces, and all your numbers will be read in correctly. If you do not, then what it does since the numbers are all together (like 034098340348) is it reads to the default number of decimal places usually 2 or 3 I think (in the case of floats).

[edited by - ju2wheels on May 2, 2002 2:55:57 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by ju2wheels
Insert a space between each int or float as you write them to the file.

That''s not a solution, and doesn''t make sense. You''re saying he should compromise the congruence of his data so he can use the inserion operator? Furthermore, he''s talking about binary input, not text.

JungleJim was right; you are wrong.

[ GDNet Start Here | GDNet Search Tool | GDNet FAQ ]
[ MS RTFM [MSDN] | SGI STL Docs | Boost ]
[ Google! | Asking Smart Questions | Jargon File ]
Thanks to Kylotan for the idea!

Share this post


Link to post
Share on other sites
quote:

That''s not a solution, and doesn''t make sense. You''re saying he should compromise the congruence of his data so he can use the inserion operator? Furthermore, he''s talking about binary input, not text.

JungleJim was right; you are wrong.



If he wants to use the insertion/extraction operators and have it work right, thenn that is the only way, so it is a solution, and how does it not make sense...

Share this post


Link to post
Share on other sites
quote:
Original post by ju2wheels
If he wants to use the insertion/extraction operators and have it work right, thenn that is the only way, so it is a solution, and how does it not make sense...

The insertion and extraction operators are for formatted text, nothing else. An attempt at any other use is a hack, not a solution.

To write binary data to a stream, use the get/put or read/write methods.

[ GDNet Start Here | GDNet Search Tool | GDNet FAQ ]
[ MS RTFM [MSDN] | SGI STL Docs | Boost ]
[ Google! | Asking Smart Questions | Jargon File ]
Thanks to Kylotan for the idea!

Share this post


Link to post
Share on other sites
The OP mentions he is working with an ofstream opened in binary mode. The formatted insertion (<< and extraction (>> operators will not work in that case, period.

A solution would be to work in binary mode and only use read/write, or work in text mode and only use the insertion and extraction operators. Mixing these two ways of doing I/O will not work.

Share this post


Link to post
Share on other sites
quote:
Original post by JungleJim
The OP mentions he is working with an ofstream opened in binary mode. The formatted insertion (<<) and extraction (>>) operators will not work in that case, period.

Yes they will.

The difference is that text streams can modify what you write if necessary for the platform; they can terminate lines if needed, they can modify \n to whatever''s appropriate, and they can do implementation-defined things to non-printable characters. Most platforms do nothing different for "text" streams, except to turn "\n" into whatever the platform requires -- \r, \r\n, or \n.

Share this post


Link to post
Share on other sites
quote:
Original post by DrPizza

The OP mentions he is working with an ofstream opened in binary mode. The formatted insertion (<<) and extraction (>>) operators will not work in that case, period.

Yes they will.


Ok, maybe my statement was a bit strong. What I meant was: it doesn't make sense to use formatted insertion and extraction operators with a file stream opened in binary mode. Formatted insertion means you convert a number to some form readable by a human. This sort of implies you insert it into a text stream.

Besides, the formatted insertion and extraction operators can skip whitespace. What does that mean, exactly, when you apply them to a stream opened in binary mode?

<< and >> are for formatted insertion and extraction from a text-mode file stream, period
quote:

The difference is that text streams can modify what you write if necessary for the platform; they can terminate lines if needed, they can modify \n to whatever's appropriate, and they can do implementation-defined things to non-printable characters. Most platforms do nothing different for "text" streams, except to turn "\n" into whatever the platform requires -- \r, \r\n, or \n.


And that conversion is something you definately would not want when working with binary files...


[edited by - JungleJim on May 3, 2002 7:20:22 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by JungleJim
Ok, maybe my statement was a bit strong. What I meant was: it doesn''t make sense to use formatted insertion and extraction operators with a file stream opened in binary mode.

Of course it does.

Imagine if you were writing a text editor that could produce files with any of the three line-ending formats. To do this with fstreams, you''d have to open the files in binary (which would better be called something like "no translation" mode). They still contain text, you simply want to make sure that no translation occurs to the text.

quote:
Formatted insertion means you convert a number to some form readable by a human. This sort of implies you insert it into a text stream.

Yes, but opening files with ios_base::binary doesn''t imply that they''re not text streams, only that they don''t get translated.

quote:
Besides, the formatted insertion and extraction operators can skip whitespace. What does that mean, exactly, when you apply them to a stream opened in binary mode?

Exactly the same as when you apply them to a stream opened in text mode.

"binary" does not mean that the file contains binary data. It means that what you read and write to it does not get translated. No more, no less.

quote:
<< and >> are for formatted insertion and extraction from a text-mode file stream, period

You can say this as much as you like, you are still wrong. The overloads work perfectly well for files opened in both translated and untranslated modes.

quote:
And that conversion is something you definately would not want when working with binary files...

You quite often don''t want it when working with text files, either.

Opening files with "binary" is not saying that the file contains binary data. It''s saying that you want reads and writes to pass through verbatim instead of being translated. That''s all.

Share this post


Link to post
Share on other sites
quote:
Original post by kamrann
I''m trying to write out various bits of data to a file, say one int, then two floats, then another int, for example. I''m using ofstream (in binary mode), and I assumed I could use the << operators to do this. But when I read back in from the file, I just get junk. Can someone explain to me how exactly the << >> operators are meant to be used.

The input operator is whitespace delimited. So just make sure you write out a space or a newline between your various variables. You should be able to read them in exactly the same way as you write them then. (Swapping the operator around, of course.)

quote:
Also, is there some way of creating a general fstream, so I dont have to cast everything to char* or something else whenever I want to read or write?

Fstreams are about as general as they come. You shouldn''t need to cast anything, certainly not floats and ints. What are you attempting?



[ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost | Asking Questions ]

Share this post


Link to post
Share on other sites
Kylotan, as for the casting, I was referring to when having to use the read/write methods, not the <> operators. Its no major problem though.
Thanks all for your help.
Cameron

Share this post


Link to post
Share on other sites