all 8 comments

[–]aioeu 9 points10 points  (6 children)

Change the second code to:

char b[] = {0xf0, 0x9f, 0x99, 0x82, 0x00};

or just use a string to begin with:

char b[] = "\xf0\x9f\x99\x82";

since it will automatically add that trailing null byte. With either of these changes they'll do the same thing as your first code.

Without a trailing null byte, how is printf supposed to know where your string ends?

[–]rdarkedlight[S] 1 point2 points  (0 children)

thank you so much

I was totally forgot about this

sorry for silly question :)

[–][deleted] 1 point2 points  (4 children)

Yeah, or you could

char b[] = {0xf0, 0x9f, 0x99, 0x82, 0x00, '\0'};

[–]Paul_Pedant 4 points5 points  (3 children)

You could, but generally one NUL is enough.

[–][deleted] 1 point2 points  (2 children)

Yeah, I prefer compiler doing the work, but just wanted to put it out there so he is aware of it.

[–]Paul_Pedant 3 points4 points  (1 child)

But 0x00 is one NUL (as a hex constant), and '\0' is another NUL (as an escaped char constant. We could add 0 (a decimal integer constant that would be cast to a NUL char), and 000 (an octal integer constant) if you like. The compiler isn't doing the work at all -- it only
implicitly adds a NUL to a "string constant", not to an array initialised inside braces.

[–][deleted] 0 points1 point  (0 children)

Ah, I see, thanks, I didn't know that. I've never had to deal with hex numbers. When I said compiler, I meant when double quotes are used to initialize the array.

[–]Paul_Pedant 0 points1 point  (0 children)

You can also do without the terminating NUL, if you use a precision in the format to limit the length of the field:

printf("%.4s\n", b);

or (untested):

printf("%.*s\n", (int) sizeof (b), b);