0

In C++ Primer 5th Edition I saw this enter image description here

when I tried to use it--- enter image description here

At this time it didn't work, but the program's output did give a weird symbol, but signed is totally blank And also they give some warnings when I tried to compile it. But C++ primer and so many webs said it should work... So I don't think they give the wrong information did I do something wrong? I am newbie btw :)

enter image description here

  • 2
    the "weird symbol" is the character with the value `255`. the second example results `c` overflowing to `0`, which, as a character, prints nothing at all. – Stefan Paul Noack Jun 21 '21 at 03:56
  • 1
    The text in the image is incorrect; `c2` has implementation-defined value (not undefined) – M.M Jun 21 '21 at 04:08
  • @stefan Then why did C++ Primer said signed should print undefined and unsigned should print 255. Does they mean something different? –  Jun 21 '21 at 04:09
  • if it is 255 when i used unsigned then why can't I see 255, and why this weird symbol :) –  Jun 21 '21 at 04:12
  • 2
    The book didn't say anything about printing – M.M Jun 21 '21 at 04:14
  • If you want to print the numerical value (in the sense that a value of `10` will print a pair of characters with value `1` and `0`) of a `char` (or `signed char` or `unsigned char`) it is necessary to convert it to an `int`, and print that. Output streams format `char` types differently (so an `unsigned` char may have a numeric value of `255`, but when output it appears as a graphic symbol - which symbol depends on the character set supported by your implementation). – Peter Jun 21 '21 at 04:14

2 Answers2

3

But C++ primer ... said it should work

No it doesn't. The quote from C++ primer doesn't use std::cout at all. The output that you see doesn't contradict with what the book says.

So I don't think they give the wrong information

No1.

did I do something wrong?

It seems that you've possibly misunderstood what the value of a character means, or possibly misunderstood how character streams work.

Character types are integer types (but not all integer types are character types). The values of unsigned char are 0..255 (on systems where size of byte is 8 bits). Each2 of those values represent some textual symbol. The mapping from a set of values to a set of symbols is called a "character set" or "character encoding".

std::cout is a character stream. << is stream insertion operator. When you insert a character into a stream, the behaviour is not to show the numerical value. Instead, the behaviour to show the symbol that the value is mapped to3 in the character set that your system uses. In this case, it appears that the value 255 is mapped to whatever strange symbol you saw on the screen.

If you wish to print the numerical value of a character, what you can do is convert to a non-character integer type and insert that to the character stream:

int i = c;
std::cout << i;

1 At least, there's no wrong information regarding your confusion. The quote is a bit inaccurate and outdated in case of c2. Before C++20, the value was "implementation defined" rather than "undefined". Since C++20, the value is actually defined, and the value is 0 which is the null terminator character that signifies end of a string. If you try to print this character, you'll see no output.

2 This was bit of a lie for simplicity's sake. Some characters are not visible symbols. For example, there is the null terminator charter as well as other control characters. The situation becomes even more complex in the case of variable width encodings such as the ubiquitous Unicode, where symbols may consist of a sequence of several char. In such encoding, and individual char cannot necessarily be interpreted correctly without other char that are part of such sequence.

3 And this behaviour should feel natural once you grok the purpose of character types. Consider following program:

unsigned char c = 'a';
std::cout << c;

It would be highly confusing if the output would be a number that is the value of the character (such as 97 which may be the value of the symbol 'a' on the system) rather than the symbol 'a'.


For extra meditation, think about what this program might print (and feel free to try it out):

char c = 57;
std::cout << c << '\n';

int i = c;
std::cout << i << '\n';

c = '9';
std::cout << c << '\n';

i = c;
std::cout << i << '\n';
eerorika
  • 232,697
  • 12
  • 197
  • 326
  • I couldn't understand some parts but i understand that i should have used int instead of char :) i am newbie i can't understand that much :( can ya tell me a place where I can learn the basics of C++ well to understand ur answer :) –  Jun 21 '21 at 06:27
  • @rafid100 Footnotes 1 and 2 are pedantic stuff that you can probably ignore as a beginner until they become relevant. This is probably a good place to start learning: https://stackoverflow.com/q/388242/2079303 – eerorika Jun 21 '21 at 11:14
  • The nul terminator is a C string convention; output functions that traffic in C strings treat it as the end of the string. That doesn't mean that `std::cout << char(0)` has to produce no output -- that inserter does not treat its argument as a C style string, but as a plain old character. Yes, the character with code point 0 typically doesn't have a textual representation, but in that regard it's no different from the character with code point 1. – Pete Becker Jun 21 '21 at 13:34
  • @PeteBecker Indeed. It would be the same for other control characters, would it not? – eerorika Jun 21 '21 at 13:36
  • @eerorika -- some control characters have well-defined "visible" effects: `\a`, `\b`, `\f`, `\n`, `\r`, `\t`, and `\v` all map to control characters but show up in the output. (The reason for putting "visible" in quotes is that `\a` is actually auditory, but it is noticeable, nonetheless). See [lex.ccon], and, in particular, the table of Escape Sequences at the end of that section. – Pete Becker Jun 21 '21 at 13:43
  • @PeteBecker I had thought of `\r\n\t\v` as "whitespace", rather than control charceters. But I suppose that's what they are. – eerorika Jun 21 '21 at 13:46
  • Re: "control character" vs. "whitespace" -- it's a matter of perspective. From the language perspective, those are whitespace; from the device perspective they're control characters. – Pete Becker Jun 21 '21 at 13:55
  • @eerorika did ya mean if the char c is 0 when signed it will print the weird symbol sorry i couldnt test it because i am in Android device right now –  Jun 21 '21 at 16:12
1

This is due to the behavior of the << operator on the char type and the character stream cout. Note, the << is known as formatted output means it does some implicit formatting.

We can say that the value of a variable is not the same as its representation in certain contexts. For example:

int main() {
    bool t = true;
    std::cout << t << std::endl; // Prints 1, not "true"
}

Think of it this way, why would we need char if it would still behave like a number when printed, why not to use int or unsigned? In essence, we have different types so to have different behaviors which can be deduced from these types.

So, the underlying numeric value of a char is probably not what we looking for, when we print one.

Check this for example:

int main() {
    unsigned char c = -1;
    int i = c;
    std::cout << i << std::endl; // Prints 255
}

If I recall correctly, you're somewhat close in the Primer to the topic of built-in types conversions, it will bring in clarity when you'll get to know these rules better. Anyway, I'm sure, you will benefit greatly from looking into this article. Especially the "Printing chars as integers via type casting" part.

rawrex
  • 4,044
  • 2
  • 8
  • 24