Skip to main content
gamedev.net
🔒 Locked

C++ I/O

Started by doctorsixstring 6 replies 350+ views
Original Post
doctorsixstring
doctorsixstring
Although I have learned a ton of C++ in the last few years, I am still using the C-style fprintf(), fopen(), sprintf(), etc. functions. I have looked at using C++ I/O functionality (cout/cin, streams), but I can''t seem to get quite as much power out of them. For instance, how would I write the following C-style line using cout or fstream? char str[256]; sprintf(str, "vector heading = %0.4f\nvector velocity = %0.2f\n# Vectors = %i\n", fHeading, fVelocity, nVectors); I know how to use cin/cout/fstream/iostream/etc. with simple text strings, but not with numberic variables (especially formatted floats/doubles). Does anyone know of a more elegant solution? I''d really like to move past the ***f() functions and get a strong handle on the C++ way. Thanks, Mike
Paradigm Shifter
Paradigm Shifter
Check out the io stream manipulators in < iomanip >.
You can write new manipulators if you want.
The ones you are interested in will be setw(n) to set output field minimum width, and setprecision(p) to set number of significant figures in float output.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley
"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley
Fruny
Fruny
If you want printf-style formatting for C++ streams, check out boost::format.

Otherwise, you need to play with the setprecision manipulator. But I will grant you, it can get ugly as hell.


  
#include <sstream>

#include <iomanip>

#include <string>

using namespace std;

stringstream ss;

ss << "vector heading = " << fixed << setprecision(4) << fHeading << endl
<< "vector velocity = " << setprecision(2) << fVelocity << endl
<< "# Vectors = " << nVectors << endl;

string str = ss.str();

// Or, if you want a C string :

char str[256];
strncpy( str, ss.c_str(), 256 );



Or, more easily with boost::format


  
#include <boost/format.hpp>

#include <string>

using namespace std;
using namespace boost;

format fmt( "vector heading = %0.4f\nvector velocity = %0.2f\n# Vectors = %i\n" );

fmt % fHeading % fVelocity % nVectors;

string str = fmt.str(); // the fmt object is now ready to accept new parameters.



Benefits ? The type tokens in the format string are indicative of the format (i.e. you request fixed-point), but do not impose the parameter type ( anything printable with << would be ok ).

A very useful reference book to have : "The C++ Standard Library" by Nicolai Josuttis.
A much more specialised book : "Standard C++ IOStreams and Locales" by Langer and Kreft.

I strongly suggest you get the first of the two books, and check out boost::format.


[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
eldee
eldee
the only thing i've got gripes with regarding the new C++ standards
is the fact that ifstream's read() will only take type char*.
very annoying.. i'll keep my file pointer for now

[edit: AP: geez man, at least use cstdio ]

-eldee
;another space monkey;
[ Forced Evolution Studios ]

::evolve::
Do NOT let Dr. Mario touch your genitals. He is not a real doctor!

[edited by - eldee on January 8, 2003 2:50:09 PM]

doctorsixstring
doctorsixstring
Thanks for the replies, guys! I think I might just stick with the C-style functions. The C++ way doesn''t really seem any better or worse, so I might as well keep using what I am more effective with.
Fruny
Fruny
quote:
Original post by eldee
the only thing i've got gripes with regarding the new C++ standards
is the fact that ifstream's read() will only take type char*.
very annoying.. i'll keep my file pointer for now



ifstream is just one specialisation of the basic_ifstream class template. If you're not satisfied with the char* parameter, you can either do a cast or use a different specialisation (assuming 'Foo' makes some sense as a character type... you may have to specialize char_traits).

e.g

std::ifstream ifs( "Foo.bin" ); // really std::basic_ifstream<char>
Foo myFoo;
ifs.read( (char*)&myFoo, sizeof( myFoo ) );
or

std::basic_ifstream<Foo> ifs_foo( "Foo.bin" );
Foo myFoo;
ifs_foo.read( &myFoo, 1 );


The functionality is there, if you only make the effort to look for it.


[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]


[edited by - Fruny on January 8, 2003 3:18:03 PM]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
null_pointer
null_pointer
quote:
the only thing i''ve got gripes with regarding the new C++ standards is the fact that ifstream''s read() will only take type char*.


The C++ standard says that a char is exactly one byte. Binary file I/O is typically done in terms of bytes. What is the problem?

A quick idea to spur conversation about alternatives:


  
# include <iostream>
 
template <class stream> class generic_stream
{
public:
operator stream& () { return static_cast <stream&> (*this); }
 
template <typename T>
void read (T* data)
{ stream.read (reinterpret_cast <char*> (data), sizeof (T)); }
 
template <typename T>
void write (const T* data)
{ stream.write (reinterpret_cast <const char*> (data), sizeof (T)); }
};
 
typedef generic_stream <std::fstream> generic_fstream;
typedef generic_stream <std::ifstream> generic_ifstream;
typedef generic_stream <std::ofstream> generic_ofstream;

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.