Difference between null terminated char (\0) and `^#` - c++

My codes are like this:
#include <iostream>
using std::cout;
using std::endl;
int main(int argc, char *argv[])
{
cout << (int)('\0') << endl;
cout << (char)(0) << endl;
return 0;
}
I expected to see in terminal like this:
$ test-program
0
$
However, what I saw is like this:
$ test-program
0
^#
$
What makes me confusing is that I think '\0' can be converted to 0. And 0 can also be casted into \0. I expected to see a null char followed with a endl, but the result is something weird like ^#.
Does anyone have ideas about this?

^# is just how your terminal emulator renders '\0'.

^# is a common representation of a null character. Similarly, ^A is used to represent a character with ordinal value 1, ^G for the character with ordinal value 7 (bell), and ^M for the character with ordinal value 13 (Carriage return).
cout << (char)0
Is just printing the character representation, rather than the integer representation

If you're looking at your terminal's output, you don't know if it's your program which doesn't behave as expected or maybe just your terminal emulator.
On UNIXoid systems, use ./myProgram | hexdump -C to see the hexadecimal output. This way you make sure your program does what you expect it to do, so it's the terminal which behaves not as (you) expected:
00000000 30 0a 00 0a |0...|
00000004
If you see the same output than I do, you're actually printing a zero '0', newline '\n', null '\0', newline '\n'. So in this case, your program behaves as you've expected.
You might want to try different terminal emulators or settings.

If you cast 0 to char, it doesn't generate '0', but '\0' -- keep in mind casting from an integral type to char creates a char with that ASCII code.
So basically, the second line is outputting a null character (ASCII 0).
If you wanted to output a '0' char, you would have needed to do something like (char) 48, because 48 happens to be the ASCII value for the character 0.

Related

Why printing out the characters “” (147, 148 ascii) does not work as expected on c++?

I do not understand what's going on here. This is compiled with GCC 10.2.0 compiler. Printing out the whole string is different than printing out each character.
#include <iostream>
int main(){
char str[] = "“”";
std::cout << str << std::endl;
std::cout << str[0] << str[1] << std::endl;
}
Output
“”
��
Why are not the two outputted lines the same? I would expect the same line twice. Printing out alphanumeric characters does output the same line twice.
Bear in mind that, on almost all systems, the maximum value a (signed) char can hold is 127. So, more likely than not, your two 'special' characters are actually being encoded as multi-byte combinations.
In such a case, passing the string pointer to std::cout will keep feeding data from that buffer until a zero (nul-terminator) byte is encountered. Further, it appears that, on your system, the std::cout stream can properly interpret multi-byte character sequences, so it shows the expected characters.
However, when you pass the individual char elements, as str[0] and str[1], there is no possibility of parsing those arguments as components of multi-byte characters: each is interpreted 'as-is', and those values do not correspond to valid, printable characters, so the 'weird' � symbol is shown, instead.
"“”" contains more bytes than you think. It's usually encoded as utf8. To see that, you can print the size of the array:
std::cout << sizeof str << '\n';
Prints 7 in my testing. Utf8 is a multi-byte encoding. That means each character is encoded in multiple bytes. Now, you're printing bytes of a utf8 encoded string, which are not printable themselves. That's why you get � when you try to print them.

Conversion from int to char failed and console prints weird symbol

I am having a weird issue and I don't know how to explain it. When I run this code it prints this symbol -> .
This is my code:
#include <iostream>
int main() {
int num = 1;
char number = num;
std::cout<<number<<std::endl;
system("PAUSE");
return 0;
}
I don't understand why. Normally it should convert the integer to char. I am using Dev C++ and my language standard is ISO C++11. I am programming for 4 years now and this is the first time I get something like this. I hope I explained my issue and if someone can help me I will be grateful.
Conversion from int to char failed
Actually, int was successfully converted to char.
Normally it should convert the integer to char.
That's what it did. The result of the conversion is char with the value 1.
Computers use a "character encoding". Each symbol that you see on the screen is encoded as a number. For example (assuming ASCII or compatible encoding) the value of 'a' character is 97.
A char with value of 1 is not the same as char with the value that encodes the character '1'. As such, when you print a character with value 1, you don't see the number 1, but the character that the value 1 encodes. In the ASCII and compatible encodings, 1 encodes a non-visible symbol "start of heading".
I wanted to print 1 as a char.
You can do it like this:
std::cout << '1' << '\n';
Then, since 4 years you seem to misunderstand what char is. It's not directly a character, but a number. It's the encoding that turns that number into a readable character.
Essentially, char i=1 is not the same as char i='1' (ascii table).

How do I print a string containing a 0 character in the middle?

I need to define an array of chars. One of the chars in the array must be 0.
I tried something like this:
array[i] = '0';
but when I send array to the output with:
cout << array << endl;
the 0 char is interpreted as a string separator, so only the part of array comprised between indices 0 and i-1 is printed.
How should I define the 0 character in such a way that array is printed as a whole sequence of chars, without interruptions? Could the problem depend on the nature of cout (I mean, maybe my assignment of 0 char is correct, but the printing function has some weird behavior I have ignored)?
Thanks for the help.
Character literal (or named as character constant in C) '0' is not the terminating zero of strings. It seems you used either '\0' or integer literal 0 instead of '0'. '\0' or 0 are indeed the terminating zero and has value 0 while '0' for example in ASCII has value 48.
Take into account that you wrote that you are programming in C but showed a C++ code snippet.:)
array[i] = '0'; // ASCII code of 0 as a character goes in
array[i] = 0; // string terminator character, can also be written as '\0', same thing
If you just want to send the ASCII character 0, you can write:
char a='0'
or
char a=48
The problem I still don't know how to solve is how to send the null byte to a serial port, because 0 or \0 are the same and always interrupt the string!

Logical comparison fails when it shouldn't C++

I've been having an issue where this comparison if (code->at(i) == guess.at(i))
is failing on even though it shouldn't as they are both '0': http://puu.sh/bvCRB/c640fb85a4.png
guess is a vector of char s(vector<char> guess){
and code is a pointer to a vector of char vector<char> * code
Notice the difference in what Visual Studio displays:
Name Char Value
code[0] '\0' 0
guess[0] '0' 48
That is, '0' (stored in guess[0]) is a character 0, with an ASCII code 48, whereas code[0] holds '\0' (see the backslash which stands for an escape character) which is a special character with an ASCII code 0 (known as a nul terminating character). Thus, they are different.
'0' and '\0'are not the same, even visual studio shows you that their values are different. '0' in hexadecimal is 30 and null terminator '\0' in hex is 00. They are not equal and their representation in memory is different, hence your comparison fails. If you look at ascii table you'll see the following:
Oct Dec Hex Char
──────────────────────────
000 0 00 NUL '\0'
060 48 30 0
'\0' is a special character that is used for example to indicate the end of a c-style string, while '0' is just an ascii character.

Wierd result (`\210`) when printing the end of a char array

My codes are like this:
int main(int argc, char *argv[])
{
char ca[] = {'0'};
cout << *ca << endl;
cout << *(ca+1) << endl;
cout << ca[1] << endl;
cout << (char)(0) << endl;
return 0;
}
The result is like this:
0
\210
\210
^#
From this thread, I knew that ^# is the same as \0 actually. However, the \210 seems not because when I use hexdump to view the result.
bash-3.2$ ./playground | hexdump -C
00000000 30 0a 88 0a 88 0a 00 0a |0.......|
00000008
It can be seen clearly that \210 is 88 instead of 00.
As I understood, ca+1 should point to a null terminator, which is \0. But why cout << *(ca+1) << endl; gives me \210 as the result?
Because you have to manually add the null terminator when declaring a character array. If you make it a string (such as in char myString[] = "hi"), then it will add a null terminator. But if you make it an array, with the braces, it will not.
As for the 0x88 byte, it just happened to be the next byte in RAM for whatever reason.
In any valid C program the string literals are always null terminated. Here you are trying to initialize the individual element of character array but just with list initialization syntax and not to a string literal. As this is static array allocated with in same function, you can even confirm this with help of sizeof operator.
doing ca should give you 1 i.e. one character array. However if you would have done something like char ca[] = "0"; then applying sizeof(ca) should give you 2 i.e. character '0' and null termination character. As aaaaaa123456789 mentioned, this is just an output now you are getting, just another byte in a memory. If you run this at some different time, you will see different output or your program may crash. referring incorrect location may cause any runtime anomaly.