tags:

views:

155

answers:

7

I am reading through a "Learn C" book right now and have come across a question I really don't understand. The point of the exercise is to find the problem with this code:

char c;

c = 'a';

printf("c holds the character %c.",c);

..and then it gives the explanation that: "The text string "a" is composed of two characters, both 'a' and the terminating zero byte. The variable c is only a single byte in size. Even if c were 2 bytes long, you couldn’t copy a text string this way. Try copying the text one byte at a time into a variable large enough to hold the text string and its terminating zero byte."

However, when I run the code above - it works perfectly fine. I thought I understood the theory behind why it is bad - the whole terminating 0 at the end of a string thing, so I rewrote the code like this to test:

char c[2];

*c = 'a';

printf("c holds the character %c.",c);

But this generates a problem. I am starting to get confused as to the problem. Wouldn't this 2nd set of code pass the letter 'a' to the pointer at c[0] and then put the terminating 0 at c[1] - fully using the 2 spaces allotted for that array?

+2  A: 

In C, single quotes imply a character constant.

Gabriel
+9  A: 

The explanation that: "The text string "a" is composed of two characters, both 'a' and the terminating zero byte.

This is true but the 'a' is not "a". 'a' is a single character. So 'a' fits very well in a char.

The example of writing one char by one into a string should look like this:

char str[2];
str[0] = 'a';
str[1] = 0; /* because nothing guarantees array items are initialized to 0 */
printf("str holds the string %s.", str);
jdehaan
+8  A: 

The text is wrong, or else you're transcribing the code incorrectly.

In C, a double-quoted string is null-terminated. A single-quoted character is just one character.

Bill Karwin
The text is not wrong at most a bit misleading, but it is correct.
jdehaan
There's nothing wrong with the code that it gives though. If the book says to find a "problem" with correct code, then the book is wrong.
David Liu
+2  A: 

In your second example code snippet, c is interpreted as a pointer to the first element in the array (i.e. as a char *), not as a char. You could either do:

printf("c holds the character %c.", *c);

or

printf("c holds the character %c.", c[0]);

or

printf("c holds the character %s.", c);

In the last example, the %s tells printf() to expect a string rather than a character. However, in that case, you must set the second element of c[] to be a "null terminator" (using e.g. c[1] = '\0'), otherwise printf() won't know where the string ends, and potentially will print an infinite amount of garbage.

Oli Charlesworth
A: 

In C, 'c' is a single character whereas, "c" is a character string. (Note the double quotes). The book author's explanation about the variable occupying 2 bytes, fits only the second case.

In your first code segment, you are assigning a perfectly valid 1-byte char to a char variable and printing it. So it works.

In your second code-segment, you are assigning a char to char array(of if you want to call it a string) and not 'null-terminating' it. When you call the printf function on it, printf does not know where the string ends. Thus the behavior of printf goes undefined here.

Sundar
A: 

Something is wrong with the explanation shown by the book. The 'a' is a single char (note the single quotes) and "a" is a string. Now "a" is indeed 0x00 terminated. But 'a' isn't.

My conclusion for now is that either something got garbled while you copied the information from the book ... or ... the title "Learn C" was the goal of the author of the book.

Niels Basjes
+1  A: 

Strings in C are actually character arrays. So char c[2]; is a declaration for c, which is an array of characters with 2 elements. Assigning it with 'a' is wrong since it is a character literal, you should assign it with "a" which is a string literal. Just remember the difference between single quotes and double quotes as stated by the earlier comments.

arscariosus