Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > iostream vs stdio.h

Reply
Thread Tools

iostream vs stdio.h

 
 
Ningyu Shi
Guest
Posts: n/a
 
      09-15-2006
I recently started to write a program in c++, which involves some I/O
of file. Quickly, I found that it's difficult to use the c++ iostream
stuff.
say I want to do
printf("%10.3f %.4f %5d",a,b,c)
in c++
is it right to write like
cout<<setprecision(3)<<setw(10)<<a<<........?
that's too complicated...
I've read a lot of old discussion on this group, still confused, is
there a easier way to do my job in c++ way? I just want some simple
controled data output.
is there a way like
cout<<fmt("%10.3f %.4f %5d")<<a<<b<<c?
thanks

 
Reply With Quote
 
 
 
 
Stuart Redmann
Guest
Posts: n/a
 
      09-15-2006
Ningyu Shi wrote:

> I recently started to write a program in c++, which involves some I/O
> of file. Quickly, I found that it's difficult to use the c++ iostream
> stuff.
> say I want to do
> printf("%10.3f %.4f %5d",a,b,c)
> in c++
> is it right to write like
> cout<<setprecision(3)<<setw(10)<<a<<........?
> that's too complicated...
> I've read a lot of old discussion on this group, still confused, is
> there a easier way to do my job in c++ way? I just want some simple
> controled data output.
> is there a way like
> cout<<fmt("%10.3f %.4f %5d")<<a<<b<<c?
> thanks
>


What about the following:

#include <iostream>
#include <sstream>
#include <iomanip>

int StringToInt(std::string stringValue)
{
std::stringstream ssStream(stringValue);
int iReturn;
ssStream >> iReturn;
return iReturn;
}

class decorated_ostream
{
public:
std::string FormatSpecifier;
std:stream* OriginalStream;

decorated_ostream& operator<<(std:stream& (__cdecl *_F)(std:stream&))
{
((*_F)(*OriginalStream));
return *this;
}
};

class ostream_decorator
{
public:
std::string FormatSpecifier;
};

ostream_decorator fmt (const char* Format)
{
ostream_decorator RetVal;
RetVal.FormatSpecifier = Format;
return RetVal;
}

decorated_ostream operator<< (std:stream& p_refLHS, ostream_decorator&
Specifier)
{
decorated_ostream RetVal;
RetVal.OriginalStream = &p_refLHS;
RetVal.FormatSpecifier = Specifier.FormatSpecifier;
return RetVal;
}

template <class T>
decorated_ostream& operator<< (decorated_ostream& p_refLHS, T p_RHS)
{
// If the format specifier is zero, we behave just like an ordinary
ostream.
if (p_refLHS.FormatSpecifier.size () == 0)
{
(*p_refLHS.OriginalStream) << p_RHS;
return p_refLHS;
}

// Search the format specifier for the first format specification.
int Temp = p_refLHS.FormatSpecifier.find_first_of ("%");
if (Temp == std::string::npos)
{
// If we haven't found any '%', we can assume that the format
string can be copied to the underlying
// stream one by one.
(*p_refLHS.OriginalStream) << p_refLHS.FormatSpecifier;
p_refLHS.FormatSpecifier.erase ();
return p_refLHS;
}
else
{
// Print the string before the '%' symbol and process the format
specifier.
(*p_refLHS.OriginalStream) << p_refLHS.FormatSpecifier.substr (0,
Temp);
p_refLHS.FormatSpecifier .erase (0, Temp + 1);

// We only process size specifier and precision of floats and doubles.
int Temp = p_refLHS.FormatSpecifier.find_first_not_of ("0123456789");
if (p_refLHS.FormatSpecifier[Temp] == '.' ||
p_refLHS.FormatSpecifier[Temp] == 'd' ||
p_refLHS.FormatSpecifier[Temp] == 'f')
{
// If Temp is non-zero, the user has supplied a width specifier.
if (Temp > 0)
{
// Parse the integer value and set it as requested width.
(*p_refLHS.OriginalStream) << std::setw (StringToInt
(p_refLHS.FormatSpecifier.substr (0, Temp)));
p_refLHS.FormatSpecifier.erase (0, Temp);
}
}
else
// TODO: do some meaningful error handling here.
throw 0;

// If there is a point in the format specification, we must search
for a precision specification.
if (p_refLHS.FormatSpecifier[0] == '.')
{
p_refLHS.FormatSpecifier.erase (0, 1);
Temp = p_refLHS.FormatSpecifier.find_first_not_of ("0123456789");
if (p_refLHS.FormatSpecifier[Temp] == 'd' ||
p_refLHS.FormatSpecifier[Temp] == 'f')
{
// If Temp is non-zero, the user has supplied a precision
specifier.
if (Temp > 0)
{
// Parse the integer value and set it as requested precision.
(*p_refLHS.OriginalStream) << std::setprecision (StringToInt
(p_refLHS.FormatSpecifier.substr (0, Temp)));
p_refLHS.FormatSpecifier.erase (0, Temp);
}
}
else
// TODO: do some meaningful error handling here.
throw 0;
}

(*p_refLHS.OriginalStream) << p_RHS;
p_refLHS.FormatSpecifier = p_refLHS.FormatSpecifier.erase (0, 1);
return p_refLHS;
}
}

int main ()
{

std::cout << fmt ("test1 %10ftest2 %4.2d") << 3.5 << 3.1416 <<
"test3" << std::endl;
return 0;
}

Above code has some drawbacks, however: only format specifications for
double and floats are recognized, and for these only the width and
precision is parsed. If you should need more, you'd have to modify the
parsing of the format specifiers. Furthermore, no type checking is
performed. This means that a user may specify "%d" but put a string as
next parameter into the decorated_ostream. Of course, you could check
this by retrieving the type of T at run-time and check against the
format specifier. You should keep in mind, that you cannot pass a second
fmt () specification into the call chain, since the second
ostream_decorator would be passed to the underlying stream, but the
resulting new decorated_ostream will be discarded. If you need this
behaviour urgently i'd think of a better solution.

Regards,
Stuart
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Semi OT: Mixing iostream and iostream.h red floyd C++ 3 03-08-2005 05:57 PM
iostream + iostream.h S. Nurbe C++ 7 01-15-2005 07:49 AM
is MS newer <iostream> is slower than older <iostream.h>? ai@work C++ 9 12-16-2004 08:21 PM
#include <iostream.h> or <iostream> John Tiger C++ 10 08-06-2003 01:30 PM
iostream::read function Lans Redmond C++ 0 06-26-2003 12:13 AM



Advertisments