468,457 Members | 1,686 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,457 developers. It's quick & easy.

printf and cout

Hello, everyone:

this is about overflow in C and C++.
int c = 400;
printf("%c", c);
it print ? on screen, and ascii of '?' is 63.
but
cout << int(char(400));
it print -112 on screen.
so, my question is why comes 63 and -112, what relations between
them,
why printf and cout behavior so differently.
both tests are in VC2005.
thanks a lot.

Mar 26 '08 #1
10 3519
int c = 400;
printf("%c", c);

it print ? on screen, and ascii of '?' is 63.

but
cout << int(char(400));

it print -112 on screen.

so, my question is why comes 63 and -112, what relations between them,
why printf and cout behavior so differently.
Hi!

both values are the same, except that the '?' is not meant as the
character '?' but as an unprintable character. It also "looks" different
than a normal '?'.
As Richard Heathfield posted in comp.lang.c try to dump the output to a file
and inspect it using some kind of hexdump/hexedit.

regards
--
Bernhard Schauer
schauer_at_cruxy_dot_net
Mar 26 '08 #2
On Mar 26, 2:05*am, Bernhard Schauer <bernhard.scha...@gmail.com>
wrote:
int c = 400;
printf("%c", c);
it print ? on screen, and ascii of '?' is 63.
but
cout << int(char(400));
it print -112 on screen.
so, my question is why comes 63 and -112, what relations between them,
why printf and cout behavior so differently.

Hi!

both values are the same, except that the '?' is not meant as the
character '?' but as an unprintable character. It also "looks" different
than a normal '?'.
As Richard Heathfield posted in comp.lang.c try to dump the output to a file
and inspect it using some kind of hexdump/hexedit.

regards

--
Bernhard Schauer
schauer_at_cruxy_dot_net
thanks.

I just know it:

Just as you say, '?' does not mean to be the result of the overflow,
but a symbol of unknown ascii character. when a number overflows by
char, and the left binary is negate, the printf will print '?'.
Mar 26 '08 #3
laikon <la****@gmail.comwrites:
Hello, everyone:

this is about overflow in C and C++.
int c = 400;
printf("%c", c);
it print ? on screen, and ascii of '?' is 63.
That would depend on the locale, on what character encoding is used by
your terminal.

Usually C char are one octet. So when you want to treat 400 as a char,
you get 400 % 256, which is 144. But 144 is not an ASCII code, and
neither the code of an ISO-8859-1 character (and therefore neither the
code of an Unicode character). It's a control code : DCS, Device
Control String. Your terminal doesn't interpret this control code, as
such, and prints its perplexity in the form of a question mark. You'd
do the same.

but
cout << int(char(400));
it print -112 on screen.
Looks like your chars are signed chars.
400 % 256 == 144 % 256 == -112 % 256

so, my question is why comes 63 and -112, what relations between
them,
why printf and cout behavior so differently.
Well they're not the same, one is a C function, the other is a C++
object. But the point is that they don't get a chance to do the same
anyways. You give the integer 400 to print, and you give the integer
-112 to cout. Try:

::printf("%d\n",int(char(400)));
cout<<int(char(400))<<endl;

and then:

::printf("%c\n",char(400));
cout<<char(400)<<endl;

and there of course, you get different results because of the way
cout handles characters, that is, as integers, but that's another
story. You could try:

char str[2];str[0]=char(400);str[1]=0;
::printf("%s\n",cstr);
cout<<cstr<<endl;

both tests are in VC2005.
thanks a lot.

--
__Pascal Bourguignon__
Mar 26 '08 #4
On 26 mar, 10:51, p...@informatimago.com (Pascal J. Bourguignon)
wrote:
laikon <lai...@gmail.comwrites:
Hello, everyone:
this is about overflow in C and C++.
int c = 400;
printf("%c", c);
it print ? on screen, and ascii of '?' is 63.
That would depend on the locale, on what character encoding is used by
your terminal.
Usually C char are one octet. So when you want to treat 400 as a char,
you get 400 % 256, which is 144. But 144 is not an ASCII code, and
neither the code of an ISO-8859-1 character (and therefore neither the
code of an Unicode character). It's a control code : DCS, Device
Control String. Your terminal doesn't interpret this control code, as
such, and prints its perplexity in the form of a question mark. You'd
do the same.
but
cout << int(char(400));
it print -112 on screen.

Looks like your chars are signed chars.
400 % 256 == 144 % 256 == -112 % 256
so, my question is why comes 63 and -112, what relations between
them,
why printf and cout behavior so differently.
Well they're not the same, one is a C function, the other is a C++
object. But the point is that they don't get a chance to do the same
anyways. You give the integer 400 to print, and you give the integer
-112 to cout.
More to the point, he told printf to convert the integer to a
char, and attempt to print that. In C++, he told the system to
convert the integer to a char, and then print integral value of
that char.
Try:
::printf("%d\n",int(char(400)));
cout<<int(char(400))<<endl;
and then:
::printf("%c\n",char(400));
cout<<char(400)<<endl;
and there of course, you get different results because of the
way cout handles characters,
I'm not sure of that, although there's really no guarantee about
much at this level. Typically, though, unless you've been
playing games with locales, you should get the same thing.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Mar 26 '08 #5
laikon wrote:
Hello, everyone:

this is about overflow in C and C++.
int c = 400;
printf("%c", c);
it print ? on screen, and ascii of '?' is 63.
but
cout << int(char(400));
it print -112 on screen.
These two things are not the same at all.
The printf version should read like this:

#include <cstdio>

int main()
{
int c = 400;
printf("%d", (char)400);
}

And, not surprisingly, it prints -112 too (on a 2s complement machine).
Mar 26 '08 #6
On Mar 26, 11:50 pm, Paul Brettschneider
<paul.brettschnei...@yahoo.frwrote:
laikon wrote:
this is about overflow in C and C++.
int c = 400;
printf("%c", c);
it print ? on screen, and ascii of '?' is 63.
but
cout << int(char(400));
it print -112 on screen.
These two things are not the same at all.
The printf version should read like this:
#include <cstdio>
int main()
{
int c = 400;
printf("%d", (char)400);
}
And, not surprisingly, it prints -112 too (on a 2s complement machine).
On a 2's complement machine with 8 bit bytes, where plain char
is signed. Exceptions to the first two conditions are fairly
rare today. But unsigned plain char is an option with a lot of
compilers, and the default on some as well (and would make life
a lot easier if you could count on it).

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Mar 27 '08 #7
Pascal J. Bourguignon wrote:
Looks like your chars are signed chars.
400 % 256 == 144 % 256 == -112 % 256
Doesn't matter if his chars are signed or not,
the C STANDARD specifically says the %c formatter
converts to unsigned char.
Mar 27 '08 #8
On Mar 26, 7:55*pm, laikon <lai...@gmail.comwrote:
Hello, everyone:

this is about overflow in C and C++.

int c = 400;
printf("%c", c);

it print ? on screen, and ascii of '?' is 63.

but
cout << int(char(400));

it print -112 on screen.

so, my question is why comes 63 and -112, what relations between
them,
why printf and cout behavior so differently.

both tests are in VC2005.

thanks a lot.
do sizeof(int) and sizeof(char)

How large number 1 byte data type can handle?

cheers,
Mar 27 '08 #9
James Kanze wrote:
On Mar 26, 11:50 pm, Paul Brettschneider
<paul.brettschnei...@yahoo.frwrote:
>laikon wrote:
this is about overflow in C and C++.
int c = 400;
printf("%c", c);
it print ? on screen, and ascii of '?' is 63.
but
cout << int(char(400));
it print -112 on screen.
>These two things are not the same at all.
The printf version should read like this:
>#include <cstdio>
>int main()
{
int c = 400;
printf("%d", (char)400);
}
>And, not surprisingly, it prints -112 too (on a 2s complement machine).

On a 2's complement machine with 8 bit bytes, where plain char
is signed. Exceptions to the first two conditions are fairly
rare today. But unsigned plain char is an option with a lot of
compilers, and the default on some as well (and would make life
a lot easier if you could count on it).
Some hardware might be optimised for signed chars and other hardware for
unsigned chars (I think this is the reason that Linux/PPC defaults to
unsigned whereas Linux/x86 traditionally uses signed).
Mar 27 '08 #10
On Mar 27, 9:52 pm, Paul Brettschneider <paul.brettschnei...@yahoo.fr>
wrote:
James Kanze wrote:
[...]
On a 2's complement machine with 8 bit bytes, where plain char
is signed. Exceptions to the first two conditions are fairly
rare today. But unsigned plain char is an option with a lot of
compilers, and the default on some as well (and would make life
a lot easier if you could count on it).
Some hardware might be optimised for signed chars and other hardware for
unsigned chars (I think this is the reason that Linux/PPC defaults to
unsigned whereas Linux/x86 traditionally uses signed).
That was the original motivation. The first two machines to
support C were the PDP-11 and the Interdata 8/32. On the first,
making char unsigned would have had a significant performance
penalty, and on the second, making it signed would have slowed
things down. And at the time, only US ASCII mattered, so even
signed, all of the encodings actually being used were positive,
and it didn't seem to make a difference.

Today, of course, most machines support either equally well, and
seven bit ASCII has been almost universally superceded by eight
bit codes: ISO 8859-n or UTF-8 (or some propriatary code pages
in console windows under Windows---probably for historical
reasons). But of course, most implementations continue to make
plain char signed, because that's the way it was on a PDP-11,
code was written which counted on it (although K&R warned from
the very beginning not to), and implementors don't want to risk
breaking it.

The result is, of course, that something like:

std::transform( s.begin(), s.end(),
s.begin(),
::tolower ) ;

results in undefined behavior.

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

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

11 posts views Thread by Pontus F | last post: by
12 posts views Thread by Minti | last post: by
3 posts views Thread by Richard Cavell | last post: by
4 posts views Thread by DeltaOne | last post: by
9 posts views Thread by liaoo | last post: by
25 posts views Thread by Podrzut_z_Laweczki | last post: by
12 posts views Thread by pai | last post: by
18 posts views Thread by Joah Senegal | last post: by
reply views Thread by NPC403 | last post: by
1 post views Thread by subhajit12345 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.