C programming: printing a null-terminated string using a character pointer

Viewed 329

I am just getting used to pointers in C. I was thinking of using %s to print the first character of a character array.

In the following code, why does %s not work, but %c works? If *my_string is dereferencing the first value of the character array, wouldn't %s try to print all the characters in memory starting at that address and continue until a null-zero character is reached?

Also, how is printf("%s", my_string) working, but printf("%s" *my_string) is not?

char* my_string = "The original value.";
printf("Value of my_string: %s\n", my_string);
my_string = "The new value.";
printf("Value of my_string: %s\n", *my_string); // Error
printf("Value of my_string: %c\n", *my_string); // Prints only the first letter 'T', but does not have any errors
3 Answers

The asterisk * de-references the pointer to the type that it is pointing to, so when my_string is a pointer to a character, *my_string is a character. Your C compiler sees your format string containing a %s and a parameter of *my_string which is a character and shows you an error.

To output the whole string, print it as in your first call to printf, to print only a single character do as you did in your last call to printf.

To understand this we need to go into how the string "The original value." is stored in the memory and what the char* my_string points to.

We can expect a memory structure like this

0xDEADBEEF    ASCII T
0xDEADBEEF+1  ASCII h
0xDEADBEEF+2  ASCII e
0xDEADBEEF+3  ASCII <space>
...
0xDEADBEEF+16 ASCII u
0xDEADBEEF+17 ASCII e
0xDEADBEEF+18 ASCII .
0xDEADBEEF+19       0

So when you have a char* my_string it points to the first character or in this case the address 0xDEADBEEF. So when you use %s in a printf it will loop through all the characters starting from the first one you pointed to until it reaches \0. But *my_string just reads the first character on that address. For that reason we need to give it a pointer.

why does %s not work, but %c works?

It is the rule by which how the printf function works. For "%s" it expects a pointer to a null ending string, and for "%c" it expects a single character.

If *my_string is dereferencing the first value of the character array, wouldn't %s try to print all the characters in memory starting at that address and continue until a null-zero character is reached?

Yes. So you must be careful in case it is a string too long and these characters are printable before the null ending.

Also, how is printf("%s", my_string) working, but printf("%s" *my_string) is not?

For "%s", it expects a pointer. "*my_string" is a character.

Related