'\0' and printf() in C
Asked Answered
E

9

22

In an introductory course of C, I have learned that while storing the strings are stored with null character \0 at the end of it. But what if I wanted to print a string, say printf("hello") although I've found that that it doesn't end with \0 by following statement

printf("%d", printf("hello"));

Output: 5

but this seem to be inconsistent, as far I know that variable like strings get stored in main memory and I guess while printing something it might also be stored in main memory, then why the difference?

Entebbe answered 7/2, 2020 at 12:54 Comment(6)
Besides the fact that your code misses at least );, what do you intend to show with that code? How do you have proven that it doesn't end with a \0?Counterproof
And what does memory it's stored in, has to do with it?Ader
In C all literal strings are really arrays of characters, which include the null-terminator.Douty
@Counterproof I think printf() return the number of character it is supposed to print on the screen.Entebbe
@AjayMishra Yes, and it indeed should have printed 5 characters. The terminating 0 byte is not printed on the screen.Counterproof
The string "hello" is an array exactly like (char[6]){'h', 'e', 'l', 'l', 'o', '\0'}Branny
P
14

The null byte marks the end of a string. It isn't counted in the length of the string and isn't printed when a string is printed with printf. Basically, the null byte tells functions that do string manipulation when to stop.

Where you will see a difference is if you create a char array initialized with a string. Using the sizeof operator will reflect the size of the array including the null byte. For example:

char str[] = "hello";
printf("len=%zu\n", strlen(str));     // prints 5
printf("size=%zu\n", sizeof(str));    // prints 6
Preciousprecipice answered 7/2, 2020 at 12:57 Comment(1)
I thought the story would be different with printf() . TBH I've no idea how printf() works.Entebbe
E
8

printf returns the number of the characters printed. '\0' is not printed - it just signals that the are no more chars in this string. It is not counted towards the string length as well

int main()
{
    char string[] = "hello";

    printf("szieof(string) = %zu, strlen(string) = %zu\n", sizeof(string), strlen(string));
}

https://godbolt.org/z/wYn33e

sizeof(string) = 6, strlen(string) = 5
Europium answered 7/2, 2020 at 12:57 Comment(0)
C
6

Your assumption is wrong. Your string indeed ends with a \0.

It contains of 5 characters h, e, l, l, o and the 0 character.

What the "inner" print() call outputs is the number of characters that were printed, and that's 5.

Counterproof answered 7/2, 2020 at 12:57 Comment(0)
D
6

In C all literal strings are really arrays of characters, which include the null-terminator.

However, the null terminator is not counted in the length of a string (literal or not), and it's not printed. Printing stops when the null terminator is found.

Douty answered 7/2, 2020 at 12:58 Comment(3)
Is there anyway to verify this without storing the string in an array?Entebbe
@AjayMishra Well the string already is in an array (as mentioned)... But if there wasn't a null terminator then printf would go out of bounds of the string, and print "random" or "garbage" characters, and return a number different from the length of the string. If you already know the length of the string you could also check if the character at that index is '\0', which will work but is technically undefined behavior if the size of the array doesn't include the terminator (as in char arr[5] = "hello";, which will not add the terminator to the array).Douty
@AjayMishra Yes E. g., you can do char * p = "Hello"; int i = 0; while (p[i] != '\0') { printf("%d: %c", i, p[i]); i++; } and see how it runs: it shows lines with indexes and the content at that line. After index 4, it finds the 0 character and breaks the while loop. There you see that there is a 0 character.Counterproof
A
6

All answers are really good but I would like to add another example to complete all these

#include <stdio.h>

int main()
{
    char a_char_array[12] = "Hello world";

    printf("%s", a_char_array);
    printf("\n");

    a_char_array[4] = 0; //0 is ASCII for null terminator

    printf("%s", a_char_array);
    printf("\n");

    return 0;
}

For those don't want to try this on online gdb, the output is:

Hello world

Hell

https://linux.die.net/man/3/printf

Is this helpful to understand what escape terminator does? It's not a boundary for a char array or a string. It's the character that will say to the guy that parses -STOP, (print) parse until here.

PS: And if you parse and print it as a char array

for(i=0; i<12; i++)
{
    printf("%c", a_char_array[i]);
}
printf("\n");

you get:

Hell world

where, the whitespace after double l, is the null terminator, however, parsing a char array, will just the char value of every byte. If you do another parse and print the int value of each byte ("%d%,char_array[i]), you'll see that (you get the ASCII code- int representation) the whitespace has a value of 0.

Ader answered 7/2, 2020 at 13:11 Comment(0)
S
4

In C function printf() returns the number of character printed, \0 is a null terminator which is used to indicate the end of string in c language and there is no built in string type as of c++, however your array size needs to be a least greater than the number of char you want to store.

Here is the ref: cpp ref printf()

Shanly answered 7/2, 2020 at 13:3 Comment(0)
C
3

But what if I wanted to print a string, say printf("hello") although I've found that that it doesn't end with \0 by following statement

printf("%d", printf("hello"));

Output: 5

You are wrong. This statement does not confirm that the string literal "hello" does not end with the terminating zero character '\0'. This statement confirmed that the function printf outputs elements of a string until the terminating zero character is encountered.

When you are using a string literal as in the statement above then the compiler creates a character array with the static storage duration that contains elements of the string literal.

So in fact this expression

printf("hello")

is processed by the compiler something like the following

static char string_literal_hello[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
printf( string_literal_hello );

Th action of the function printf in this you can imagine the following way

int printf( const char *string_literal )
{
    int result = 0;

    for ( ; *string_literal != '\0'; ++string_literal )
    {    
        putchar( *string_literal );
        ++result;
    }

    return result;
}

To get the number of characters stored in the string literal "hello" you can run the following program

#include <stdio.h>

int main(void) 
{
    char literal[] = "hello";

    printf( "The size of the literal \"%s\" is %zu\n", literal, sizeof( literal ) );

    return 0;
}

The program output is

The size of the literal "hello" is 6
Chair answered 7/2, 2020 at 14:24 Comment(0)
S
0

You have to clear your concept first.. As it will be cleared when you deal with array, The print command you are using its just counting the characters that are placed within paranthesis. Its necessary in array string that it will end with \0

Steato answered 10/2, 2020 at 7:40 Comment(0)
T
0

A string is a vector of characters. Contains the sequence of characters that form the string, followed by the special ending character string: '\ 0'

Example: char str[10] = {'H', 'e', 'l', 'l', 'o', '\0'};

Example: the following character vector is not one string because it doesn't end with '\ 0'

char str[2] = {'h', 'e'};

Tupungato answered 13/2, 2020 at 14:39 Comment(1)
There are no vectors in C, I guess.Entebbe

© 2022 - 2024 — McMap. All rights reserved.