473,847 Members | 1,756 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

formatted output question with strings

Hi all,

I was wondering how I can perform formatted output with C++ strings. For
example, suppose I have in plain C:

sprintf(C_strin g, "%5.2f %6d");

How can I do such a thing with C++ strings? Using a string stream and
the << operator does not give me the formatting control like sprintf. Or
did I miss something.... :-|

Jeroen
Jul 23 '07 #1
6 3689
Jojo <no*****@thanx. comwrites:
>Hi all,
>I was wondering how I can perform formatted output with C++ strings. For
example, suppose I have in plain C:
sprintf(C_strin g, "%5.2f %6d");
???
>Or did I miss something.... :-|
Look up fill, width, adjustfield, setprecision, floatfield etc. E.g.

cout << 1331 <<endl;
cout << "In hex " << hex<< 1331 <<endl;

cout << 1331.123456 <<endl;
cout.setf(ios:: scientific,ios: :floatfield);
cout <<1331.123456 <<endl;
cout << setprecision(3) << 1331.123456 <<endl;
cout << dec << 1331 <<endl;
cout.fill('X');
cout.width(8);
cout << 1331 <<endl;
cout.setf(ios:: left,ios::adjus tfield);
cout.width(8);
cout << 1331 <<endl;

Jul 23 '07 #2
Tim Love schreef:
Jojo <no*****@thanx. comwrites:
>Hi all,
>I was wondering how I can perform formatted output with C++ strings. For
example, suppose I have in plain C:
> sprintf(C_strin g, "%5.2f %6d");
???
I was a bit in a hurry, I forgot the numeric arguments...
>
>Or did I miss something.... :-|
Look up fill, width, adjustfield, setprecision, floatfield etc. E.g.

cout << 1331 <<endl;
cout << "In hex " << hex<< 1331 <<endl;

cout << 1331.123456 <<endl;
cout.setf(ios:: scientific,ios: :floatfield);
cout <<1331.123456 <<endl;
cout << setprecision(3) << 1331.123456 <<endl;
cout << dec << 1331 <<endl;
cout.fill('X');
cout.width(8);
cout << 1331 <<endl;
cout.setf(ios:: left,ios::adjus tfield);
cout.width(8);
cout << 1331 <<endl;
I'll look that up. At first glance, the C++ method seems much less
'comprehensive' than sprintf. But I think it's better for me to get rid
of my plain-C habits when coding C++ :-)

Thanx,

Jeroen
Jul 23 '07 #3
Jojo wrote:
I'll look that up. At first glance, the C++ method seems much less
'comprehensive' than sprintf. But I think it's better for me to get rid
of my plain-C habits when coding C++ :-)
The C-style format string functions are compact, relatively easy
to learn and remember, and fast. Once you get the hang of them, it's
very easy to perform relatively complex formatting with a very small
amount of code which only takes a small amount of time to write.
Also, you never need to worry if some formatting setting "leaks" or
not (ie. if the stream will "remember" that setting or forget about
it immediately after printing the value).
The C++-style printing functions are much more verbose, and a
complex C one-liner can easily become over a dozen of lines of C++
(or, alternatively, a dozen of << operator calls in a row) using
diverse function names from <iostreamand <iomanip>. In some cases
it also feels a bit inconsistent whether some stream setting is
remembered or forgotten between << operator calls. Most are forgotten,
but some are remembered, causing potential "formatting leaks".

On the other hand:

C-style printing functions lack abstraction, which is the whole point
in the C++-style ones. For example, assume you have this:

typedef int MyIndex;
....
// Somewhere else:
MyIndex index;
....
std::printf("Th e value is: %i\n", index);

The printf() breaks the abstraction of 'MyIndex' because it assumes
it's an int. If you later change the typedef to:

typedef long MyIndex;

the printf() will break if long is larger than int (which is usually
the case in 64-bit systems). Even if the compiler is so smart as to
warn you about the incompatible printf format string, it could still
be tedious to go and change every single printf which uses that type
(which is something you wanted to avoid doing by using the typedef
in the first place).

Getting around this problem can be done, in a limited way, with all
kinds of awkward kludges, such as:

typedef int MyIndex;
#declare MyIndexFormatSt ring "%i"
....
std::printf("Th e value is: " MyIndexFormatSt ring "\n", index);

Of course this breaks immediately if you change MyIndex to something
not supported by printf(), such as a class.

Naturally you could try to avoid this problem by writing a function
for the only purpose of printing your MyIndex, like this:

void printMyIndex(My Index value);
....
std::printf("Th e value is: ");
printMyIndex(in dex);
std::printf("\n ");

But this has two problems: You already lost the advantage over
the C++-way (ie. compactness), and you can't specify the formatting
for printing the value anylonger. You would have to add even more
kludges to this if you wanted to be able to specify the formatting:

void printMyIndex(My Index value, const char* format);
....
std::printf("Th e value is: ");
printMyIndex(in dex, "05");
std::printf("\n ");

Of course if you wanted that width parameter to be defined by
a variable instead of being a string literal, it would become even
more complicated and awkward. The more you develop this further,
the more you are actually re-implementing C++ printing functions.

Also, the lack of abstraction causes a really bad breakdown with
templates. Consider:

template<typena me T>
void print(const T& value)
{
std::printf("?? ?", value); // What to write here???
}

The big advantage of C++-style printing is that it's abstract.
You don't have to worry about types. For example:

std::cout << index << std::endl; // I don't care what 'index' is.

Or:

template<typena me T>
void print(const T& value)
{
std::cout << T << std::endl; // It doesn't matter what T is.
}

If you create your own class and you want to support printing it
in the regular way, you can! So it's perfectly possible to do this:

class MyIndex { ... };
....
MyIndex index;
....
std::cout << index << std::endl;

That MyIndex could be an int, a long, a double, a string or your
own Class, it doesn't matter. You don't have to specify the type
explicitly in the printing command, unlike in C.
Jul 23 '07 #4
On Jul 23, 9:39 am, Jojo <no_m...@thanx. comwrote:
I was wondering how I can perform formatted output with C++ strings. For
example, suppose I have in plain C:
sprintf(C_strin g, "%5.2f %6d");
How can I do such a thing with C++ strings?
To do exactly the above is a bit awkward, since you need several
manipulators. But normally, you only do something like the
above because C doesn't offer any alternative. What is the
first argument? What is the second? What semantic
characteristic does the first have which means that it should be
formatted using %5.2f, for example. In C++, you define the
formatting for such semantic characteristics , then write
something like:

... << ItsAToto << totosValue << ...

Something like ItsAToto is called a manipulator. Anytime you
write an application, you define the logical manipulators for
the various semantics that you want to support on output. That
way, if the request comes that all Toto now have to be output
with three digits after the decimal, you just change the
manipulator.

Note that most of the time, you're not outputting int's or
double's, but user defined types, which already have a specific
application dependant semantic. In such cases, the type of
"totosValue " says it all, and you don't need the manipulator.

(In text processing, this is known as logical mark-up. Roughly
speaking: C requires you to specify the physical mark-up,
locally, at each output site. C++ allows you to define a style
sheet.)
Using a string stream and
the << operator does not give me the formatting control like sprintf.
It gives you a lot more.
Or did I miss something.... :-|
If you're not familiar with maniipulators, or user defined
operator<<, you've missed practically all of iostream. (The
third important point is user defined streambufs.)

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jul 24 '07 #5
On Jul 23, 12:45 pm, Juha Nieminen <nos...@thanks. invalidwrote:
Jojo wrote:
I'll look that up. At first glance, the C++ method seems much less
'comprehensive' than sprintf. But I think it's better for me to get rid
of my plain-C habits when coding C++ :-)
The C-style format string functions are compact, relatively easy
to learn and remember, and fast.
They're compact. That's all you can say for them. They're
very, very limited in what they can do, however, and they're
very, very low level, and don't support higher level
abstractions. They also quite exoteric; even after 25 years of
using them, and actually having written an implementation of
printf, I still have to check with the manual for anything but
the simplest formatting.
Once you get the hang of them, it's
very easy to perform relatively complex formatting with a very small
amount of code which only takes a small amount of time to write.
And it's impossible to write any maintainable code, because the
low level formatting details creep down into the high level
output statements.
Also, you never need to worry if some formatting setting "leaks" or
not (ie. if the stream will "remember" that setting or forget about
it immediately after printing the value).
The C++-style printing functions are much more verbose, and a
complex C one-liner can easily become over a dozen of lines of C++
(or, alternatively, a dozen of << operator calls in a row) using
diverse function names from <iostreamand <iomanip>.
Not if you use it correctly. (Anything can be abused, of
course.) The difference is that in the C output, you have to
provide all of the information for physical formatting in the
single statement. In C++, you provide the information for the
physical formatting in the manipulator (which works more or less
like a style sheet in a word processor); the client code just
invokes the correct logical manipulator. And most of the time,
even that isn't necessary, because all of the logical
information for formatting is implicit in the type of the
expression. So you end up with:

std::cout << myVariable ;

instead of:

printf( "%-30s %5.2f %3d",
myVariable.getN ame(),
myVariable.getV alue1(),
myVariable.getV alue2() ) ;

(What was that about printf being compact?) And of course, the
C++ version continues to work correctly when value2 is changed
from int to long, or when an additional value is added, or when
it is suddenly decided that value one need three digits after
the decimal.
In some cases it also feels a bit inconsistent whether some
stream setting is remembered or forgotten between << operator
calls. Most are forgotten, but some are remembered, causing
potential "formatting leaks".
That's probably the one real pain of iostream formatting. All
of the formatting flags except width are "sticky". So you throw
in a quick additional output for debugging purposes:

std::cout << std::hex << value << std::endl ;

and all of the output which follows is in hex. (It's a
"feature" when outputting tabular data, of course: set the
precision once, before iterating over the table. But
generally...)

My own manipulators restore the original formatting flags in
their destructor, i.e. at the end of the full expression. And
of course, I've got an RAII class for restoring the original
format as well, which can be used in a function which modifies
formatting. But I agree that such things really shouldn't be
necessary.

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jul 24 '07 #6
James Kanze schreef:
On Jul 23, 9:39 am, Jojo <no_m...@thanx. comwrote:
>I was wondering how I can perform formatted output with C++ strings. For
example, suppose I have in plain C:
> sprintf(C_strin g, "%5.2f %6d");
>How can I do such a thing with C++ strings?

To do exactly the above is a bit awkward, since you need several
manipulators. But normally, you only do something like the
above because C doesn't offer any alternative. What is the
first argument? What is the second? What semantic
characteristic does the first have which means that it should be
formatted using %5.2f, for example. In C++, you define the
formatting for such semantic characteristics , then write
something like:

... << ItsAToto << totosValue << ...

Something like ItsAToto is called a manipulator. Anytime you
write an application, you define the logical manipulators for
the various semantics that you want to support on output. That
way, if the request comes that all Toto now have to be output
with three digits after the decimal, you just change the
manipulator.

Note that most of the time, you're not outputting int's or
double's, but user defined types, which already have a specific
application dependant semantic. In such cases, the type of
"totosValue " says it all, and you don't need the manipulator.

(In text processing, this is known as logical mark-up. Roughly
speaking: C requires you to specify the physical mark-up,
locally, at each output site. C++ allows you to define a style
sheet.)
>Using a string stream and
the << operator does not give me the formatting control like sprintf.

It gives you a lot more.
>Or did I miss something.... :-|

If you're not familiar with maniipulators, or user defined
operator<<, you've missed practically all of iostream. (The
third important point is user defined streambufs.)
Well, maybe I can see that I didn't miss it because I haven't take a
close look at it yet... :-) Or is this too far from programmers logic?
Nevertheless, thanks for your explanation and I'll definitly take a deep
dive into iostream to become more familiar with it.

Jeroen
>
--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jul 25 '07 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
2121
by: Craig Thomson | last post by:
Do people generally try and output nicely formatted html from their scripts? I have been trying to, with variable indenting for tables etc. It makes it easier to see the html and perhaps debug it, but it can make ugly looking scripts. What's the general consensus? Craig
4
5892
by: Joe Flynt | last post by:
I'm try to display the output of ipconfig.exe to the web browser using: Apache/2.0.48 (Win32) mod_python/3.1.2b Python/2.3.2 but when I view http://server/cgi-bin/test.py i get the following format of output: ['\r\n', 'Windows IP Configuration\r\n', '\r\n', etc. How do I get it to display the same output as if I had executed the
4
4305
by: Joerg Lehmann | last post by:
I am using Python 2.2.3 (Fedora Core 1). The problem is, that strings containing umlauts do not work as I would expect. Here is my example: >>> a = 'äöü' >>> b = '123' >>> print "%-5s %-5s\n%-5s %-5s" % (a,a,b,b) äöü äöü 123 123 I would expect, that the displayed width of a or b is the same: 5 characters.
2
1793
by: Mark | last post by:
How do I output formatted numerical data to an external (text) file. At a minimum I want to specify the number of decimal places to print. Ideally I'd like the type of control the fortran FORMAT statement offers. I'm sure this is easy, but I can't seem to find the answer! I want an output file to look like this: 0.1 0.8575 0.2 12.0900 0.4 345.0000
6
2206
by: Jason Heyes | last post by:
I am starting to worry about the performance of formatted read/write operations on data-redundant objects in my program.What can I do to improve this performance should it become an issue? Thanks.
2
3514
by: Steven T. Hatton | last post by:
I'm still not completely sure what's going on with C++ I/O regarding the extractors and inserters. The following document seems a bit inconsistent: http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#1 Copying a file: WRONG WAY: #include <fstream> std::ifstream IN ("input_file"); std::ofstream OUT ("output_file");
3
3381
by: Craig Petrie | last post by:
Hi, I have a large table in Word 2003 that has formatted text in the cells and wish to read and convert a cells formatted contents to html output via vb.net code. The formatting contains the following: bold text, italic text, superscript & subscript text, bullet points. The output html is then saved in an XML file as a CDATA section for later use in the application when formatted output is required. I have looked up many sites on the...
6
2720
by: bfowlkes | last post by:
Hello, I am trying to parse two pre-formatted text files and write them to a different files formatted in a different way. The story about this is I was hired along with about 20 other people and it seems we are trying to learn the whole C language in two weeks! To top it all off, I was an English Major, but I'm trying my best. Ok back to the program. So we have two files product_catalog.txt and sales_month.txt The info in...
6
1718
by: Prime Mover | last post by:
In C, if I have three variables obtained in a loop like: for(i=0;i<N;i++) { x = ....{expression here}; y = ....{expression here}; z = ....{expression here}; }
0
10983
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10648
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10707
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10341
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7056
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5719
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4529
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
4119
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3164
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.