3

For the following code, on my PC, char \0 will always results in a space (when printing using cout). However, on my friend's PC, the result of char \0 will always results in a char a. Code and screenshots are as follows:

#include <iostream>
using namespace std;

// Function main
int main()
{
    cout << "xxx" << '\0' << "yyy" << endl;
    return 0;
}

enter image description here enter image description here

Left: on my PC. Right: on my friend's PC.

What's going on here? Why are the results different on different PCs?

PS:

  1. The results will still be different even we share the same executable exe file (i.e. compiled on my PC and run on both PCs).

  2. We both use visual studio 2010 also with same project character set.

  3. There maybe some buffer overrun here, but please pay attention to the fact that I will always get a space while my friend will always get a char a.

  4. It shares the same feature if we both do cout<<ends.

herohuyongtao
  • 49,413
  • 29
  • 133
  • 174
  • @MitchWheat What do you mean by `bad code`? – herohuyongtao Jan 01 '14 at 08:55
  • 2
    post the code. you shouldn't get an a char.. – MoonBun Jan 01 '14 at 08:55
  • 2
    I think instead of different PCs you should have mention different compilers.. – Digital_Reality Jan 01 '14 at 09:00
  • Why is this tagged both C++ and C? Have you compiled (and seen the problem) in both languages? – JBentley Jan 01 '14 at 09:04
  • 1
    This seems hard to believe. How about posting the full code along with a screenshot of the output when you run it on your friend's computer? – David Grayson Jan 01 '14 at 09:04
  • Yes, please post the **actual** code, not just a made up snippet. In a standard console you shouldn't even be able to *see* the space, so I'm assuming your actual code is outputting something else than just `\0`. It's time for a [SSCCE](http://sscce.org/). – JBentley Jan 01 '14 at 09:06
  • This is really weird, what you say makes no sense, please post all of you code – MoonBun Jan 01 '14 at 09:08
  • http://ideone.com/aTtkPY – JBentley Jan 01 '14 at 09:15
  • Is the same executable run on friend's PC exhibit difference? – doptimusprime Jan 01 '14 at 09:19
  • On my Win7 machine I get the same result as your "left" screenshot when compiled with VS2010. – JBentley Jan 01 '14 at 09:19
  • @dbasic Yes, we share the same code. – herohuyongtao Jan 01 '14 at 09:20
  • 1
    @herohuyongtao dbasic is asking if you are running the same **executable** i.e. compiled once in a single environment, then run in two different environments, as opposed to the same code being compiled in two environments. – JBentley Jan 01 '14 at 09:22
  • @JBentley I see, I will test right now. – herohuyongtao Jan 01 '14 at 09:23
  • @JBentley & dbasic: Still differnt even share the same executable file. – herohuyongtao Jan 01 '14 at 09:27
  • Are both of them using the same DLLs? Assuming windows, try building as /MT instead of /MD i.e. cout is statically linked. Also, is one running from cmd and the other running from command? There are two command prompts in Windows. – cup Jan 01 '14 at 09:47
  • @cup Still different even building as `/MT`. – herohuyongtao Jan 01 '14 at 10:12
  • 1
    Looks to me like the font size is different - is it possible that it's also a different actual font? The "look" of a particular (printable or non-printable) depends on the actual font used, I'd say. – Mats Petersson Jan 01 '14 at 11:33
  • @MatsPetersson Yes, you are right. It is because we use different font size. I just changed my PC font to be the same with my friend's (larger). It turns out `a` instead of `space`. Why not you answer it in the following and I will accept it as the answer (perhaps with more details)? Thanks. – herohuyongtao Jan 01 '14 at 11:57

5 Answers5

6

The character \0, or the ASCII 0, is not a printable character, there's no standard way to output it.

Printable ASCII range from 0x20 to 0x7E, see Wikipedia:ASCII

herohuyongtao
  • 49,413
  • 29
  • 133
  • 174
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
2

For a "non-printable character" (which for ASCII is anything outside the range of 0x20-0x7e [*]), output is technically undefined, and the actual visual output will depend on several things:

  1. The actual output device - if you view the character on a Windows command line prompt, it may well look different to a Terminal window under Linux, and using a genuine (30+ year old) VT100 terminal, it will most likely look different again. (In fact, when I first used to write code for terminals that used serial input, we used to "pad" certain control sequences with NUL characters, because the terminal would drop some characters when the escape sequence was "complicated" - say a clear-screen, it may not receive the next 5-6 characters, so we'd add an extra 10 NUL characters to, so that we'd lose the NUL's rather than part of the meaningful text we wanted to print on the screen).

  2. When applicable, the font selected to show the text may also matter (this appears to be the case in this particular situation, but don't rely on it). Of course, this applies also to printable characters, but aside from some "special" fonts (Zapf Dingbats, Symbols are obvious examples), the "printable range" does match what we expect. The "non-printable" range is not so well-defined.

  3. The method of actual printing - for example using cout or printf will have a different result than "poking characters into the frame-buffer memory on a PC [in text mode]".

For consistent results of printing non-printable characters, you will need to process them into something that is defined as printable.

[*] Many systems support extended ranges, for example the original IBM/PC has a range of 0x20-0xff, and modern systems use multiple bytes to represent characters that are "non-printable" in for example UTF-8 encoding, where commonly used characters [in European languages] are encoded with a single byte, and characters that are less common get a two, three or four-byte encoding. Even here, the actual output depends on the exact font chosen.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
1

As stated, it is implementation-defined. On my terminal, I get a ^@. The NULL terminator is used for printing strings, but in this case, you're trying to output the character itself (and it will have varying representations, from random characters, to nothing.)

herohuyongtao
  • 49,413
  • 29
  • 133
  • 174
0

'\0' is a termination char, to know where the string ends, so for example this will print ab:

#include <iostream>

int main(int argc, char* argv[])
{
    char str[]= { 'a', 'b', '\0' };
    std::cout <<str<< std::endl;
    return 0;
}

If you print just the last char it shouldn't print anything but terminate immediately without printing anything.

The space you are talking about is probably caused by the std::endl

There is no undefined behaviour here, undefined behaviour is usually caused in the reverse case, where there is no termination char('\0') and then you print memory that is out of your allocated block and what you print is then undefined.

Edit:

This is really weird, what you say makes no sense, please post all of you code

MoonBun
  • 4,322
  • 3
  • 37
  • 69
0
#include < iostream >
using namespace std;
int main()
{
    cout << "xxx" << '\0' << "yyy" << endl;
    return 0;
}

I don't know why you are getting different o/p . check once with g++. I got this o/p with g++

enter image description here

user2760375
  • 2,238
  • 2
  • 22
  • 29