Null character and fixed strings

E

ehabaziz2001

Hi,
Till now I do not understand how the null character automatically added
to the end of the string and it is not an element of the string array .
All books said the null character (\0) added automatically to the end
of the string.

Let say
char name[9]="123456789"
If entered the name in a loop;

for (i=0;i<9;i++)
printf("%c",name);

printf("%c",name[i+1]);


will I see name[10] as \0 Null character ?
 
I

Ian Malone

Hi,
Till now I do not understand how the null character automatically added
to the end of the string and it is not an element of the string array .
All books said the null character (\0) added automatically to the end
of the string.

Let say
char name[9]="123456789"
If entered the name in a loop;

In this assignment the compiler copies from the
constant nul terminated string, which has elements
"123456789\0" to the array 'name', which has space
for 9 elements, so it stops at '9'. What you get
is not a nul terminated string, but a nine char
long array holding the characters 1 to 9.
for (i=0;i<9;i++)
printf("%c",name);

printf("%c",name[i+1]);


Here you go wrong, accessing the 10th element of a
9 element array.
will I see name[10] as \0 Null character ?

Not in your example (you invoke undefined behaviour when
you access name[9], because name is only 9 in size).

When you exit the loop i==9, not 10 (assuming this
is a snippet of code and you've previously done things
like "#include <stdio.h>" and declared i). You are
accessing name[9], which is the 10th element of the
array (starting from name[0]).

To get the terminating nul copied to name either declare
it like:
char name[10] = "123456789";

So it is big enough to hold the terminating nul. Or:
char name[] = "123456789"

The compiler looks at the assignment and makes name
big enough to hold the entire string. "sizeof name"
will tell you how big that is.
 
E

ehabaziz2001

What you mean that is always a must to leave en element space in the
end of an array string to copy the null character by the compiler ?
If I did not what are the consequneces ?
 
F

Flash Gordon

Hi,
Till now I do not understand how the null character automatically added
to the end of the string and it is not an element of the string array .
All books said the null character (\0) added automatically to the end
of the string.

Let say
char name[9]="123456789"
If entered the name in a loop;

for (i=0;i<9;i++)
printf("%c",name);

printf("%c",name[i+1]);


will I see name[10] as \0 Null character ?


No for 2 reasons.
1) Arrays are indexed from 0 not one, so you meant name[9]
2) You *explicitly* told the compiler to only allocate space for 9
chars.

If you do
char name[] = "123456789"
the compiler will allocate space for 10 chars assuming you wanted a
string (which in C *must* be terminated by a \0) rather than an array of
chars that is not a string.

Equally, if you use a string literal somewhere other than initialising
an array the compiler will add the \0 on the end, so you can do things like:

char *name = "dummy"
....
if (strcmp(name,"fred"))

without having to explicitly add the \0 yourself.

If you did
char name[some_number_larger_than_9] = "123456789"
Then elements name[9] to the end of the array would be set to \0, but
that is for a different reason.
 
I

Ian Malone

<pertinent references reinserted, to quote from
others on this group,
"Please quote enough of the previous message for context. To do so from
Google, click "show options" and use the Reply shown in the expanded
header.">

>> Let say
>> char name[9]="123456789"
>> If entered the name in a loop;
>>
>

Ian said:
> In this assignment the compiler copies from the
> constant null terminated string, which has elements
> "123456789\0" to the array 'name', which has space
> for 9 elements, so it stops at '9'. What you get
> is not a null terminated string, but a nine char
> long array holding the characters 1 to 9.

What you mean that is always a must to leave en element space in the
end of an array string to copy the null character by the compiler ?
If I did not what are the consequneces ?

It is not a must, but it does make sense. The consequence
in this case is that the null terminating character is not
copied. As a result what you have is an array of characters,
not a C-style null terminated array. This means most (all?)
of the standard functions for strings (such as strlen) will
not work with it. The least error prone solution is to
provide an array of unknown size to be initialized.
>> char name[] = "123456789"

What I'm curious about, if anyone reading knows, is what happens
when the array is not large enough to hold a character in the
initializer other than '\0'?
6.7.8 of C9X FCD:
[#2] No initializer shall attempt to provide a value for an
object not contained within the entity being initialized.

[#14] An array of character type may be initialized by a
character string literal, optionally enclosed in braces.
Successive characters of the character string literal
(including the terminating null character if there is room
or if the array is of unknown size) initialize the elements
of the array.

14 seems to make special provision for the case of the null
character alone, 2 seems to imply the general case:
char too_short[1] = "too_long";

Is undefined: am I reading that right?
 
K

Keith Thompson

What you mean that is always a must to leave en element space in the
end of an array string to copy the null character by the compiler ?
If I did not what are the consequneces ?

One more time.

If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.
 
E

ehabaziz2001

I need to complete that discussion
-I still need to know when I should add the null character at the end
of the string array ?
-When the compiler add it automatically ?
-should I add a space element to the end of the array to keep for the
compiler space for that automatically addition ?
 
C

Christopher Benson-Manica

I need to complete that discussion

What discussion? Hint: Quoting relevant portions of preceding
conversations is enormously helpful.
-I still need to know when I should add the null character at the end
of the string array ?

If it isn't there, you don't have a string. Sometimes the standard
string functions take care of it for you, sometimes not. Consult your
favorite references for details.
-When the compiler add it automatically ?

const char *mystr="foo"; /* terminating null character taken care of */
char mystr[]="foo"; /* again taken care of */
char mystr[]={ 'f', 'o', 'o', '\0' }; /* must be explicit here */
-should I add a space element to the end of the array to keep for the
compiler space for that automatically addition ?

Any character array you plan to put a string in must be at least one
byte larger than the length of that string, to accomodate the null
terminating character. IOW, "yes".
 
K

Keith Thompson

Christopher Benson-Manica said:
(e-mail address removed) wrote: [...]
-When the compiler add it automatically ?

const char *mystr="foo"; /* terminating null character taken care of */
char mystr[]="foo"; /* again taken care of */
char mystr[]={ 'f', 'o', 'o', '\0' }; /* must be explicit here */

Another example:

char arr[3] = "foo"; /* special case, no terminating null character */

For this reason, it's usually better *not* to specify the size of a
char array initialized with a string literal, unless you specifically
don't want the terminating '\0' or you want the array to be bigger
than the string:

char arr[20] = "foo"; /* first 4 chars are 'f', 'o', 'o', '\0' */
 
M

Mark McIntyre

char arr[20] = "foo"; /* first 4 chars are 'f', 'o', 'o', '\0' */

ICBW, but in fact isn't it the case that the first three chars are
'f','o', and 'o' and all the rest are '\0' ?
 
F

Flash Gordon

Mark said:
char arr[20] = "foo"; /* first 4 chars are 'f', 'o', 'o', '\0' */

ICBW, but in fact isn't it the case that the first three chars are
'f','o', and 'o' and all the rest are '\0' ?

You are, indeed, correct. Of course not string function is going to look
beyond the first of those '\0's, which may be why Keith only mentioned
the first.

Your point is important when declaring a large buffer since you could
waste a significant amount of time. E.g.

void foo(void)
{
char bigbuf[1024] = "stuf:";
/* do stuff */
}

if foo is called a lot.
 
M

Mabden

Flash Gordon said:
Mark said:
char arr[20] = "foo"; /* first 4 chars are 'f', 'o', 'o', '\0' */

ICBW, but in fact isn't it the case that the first three chars are
'f','o', and 'o' and all the rest are '\0' ?

You are, indeed, correct. Of course not string function is going to look
beyond the first of those '\0's, which may be why Keith only mentioned
the first.

Whaaa..t? ICBR, but...What the hell would make anything beyond arr[3]
anything?! That's all unitialized space.
 
F

Flash Gordon

Mabden said:
Mark said:
On Thu, 20 Oct 2005 02:42:49 GMT, in comp.lang.c , Keith Thompson


char arr[20] = "foo"; /* first 4 chars are 'f', 'o', 'o', '\0' */

ICBW, but in fact isn't it the case that the first three chars are
'f','o', and 'o' and all the rest are '\0' ?

You are, indeed, correct. Of course not string function is going to
look
beyond the first of those '\0's, which may be why Keith only mentioned
the first.

Whaaa..t? ICBR, but...What the hell would make anything beyond arr[3]
anything?!

The C standard. As it has since 1989.
> That's all unitialized space.

No, the standard specified that the entire array is initialised.

PS. I decided to let you out see if you have improved.
 
D

David Resnick

Mabden said:
Flash Gordon said:
Mark said:
On Thu, 20 Oct 2005 02:42:49 GMT, in comp.lang.c , Keith Thompson

char arr[20] = "foo"; /* first 4 chars are 'f', 'o', 'o', '\0' */

ICBW, but in fact isn't it the case that the first three chars are
'f','o', and 'o' and all the rest are '\0' ?

You are, indeed, correct. Of course not string function is going to look
beyond the first of those '\0's, which may be why Keith only mentioned
the first.

Whaaa..t? ICBR, but...What the hell would make anything beyond arr[3]
anything?! That's all unitialized space.

Because the standard says so? From N869 section 6.7.8:

[#14] An array of character type may be initialized by a
character string literal, optionally enclosed in braces.
Successive characters of the character string literal
(including the terminating null character if there is room
or if the array is of unknown size) initialize the elements
of the array.

[#21] If there are fewer initializers in a brace-enclosed
list than there are elements or members of an aggregate, or
fewer characters in a string literal used to initialize an
array of known size than there are elements in the array,
the remainder of the aggregate shall be initialized
implicitly the same as objects that have static storage
duration.

(and this example helps clarify that the quoted string is in fact
the same as a brace enclosed list):
[#32] EXAMPLE 8 The declaration

char s[] = "abc", t[3] = "abc";

defines ``plain'' char array objects s and t whose elements
are initialized with character string literals. This
declaration is identical to

char s[] = { 'a', 'b', 'c', '\0' },
t[] = { 'a', 'b', 'c' };

-David
 
M

Mabden

Flash Gordon said:
Mabden said:
Mark McIntyre wrote:

On Thu, 20 Oct 2005 02:42:49 GMT, in comp.lang.c , Keith Thompson


char arr[20] = "foo"; /* first 4 chars are 'f', 'o', 'o', '\0' */

ICBW, but in fact isn't it the case that the first three chars are
'f','o', and 'o' and all the rest are '\0' ?

You are, indeed, correct. Of course not string function is going to
look
beyond the first of those '\0's, which may be why Keith only mentioned
the first.

Whaaa..t? ICBR, but...What the hell would make anything beyond arr[3]
anything?!
The C standard. As it has since 1989.
That's all unitialized space.
No, the standard specified that the entire array is initialised.

I still haven't gotten my answer to how automatic vs global variables
(pointers in particular) are initialized, so I remain, as always
ignor... unenlightened.

So are you saying this is true in global space, or did I miss a post
that said it was within a function?
PS. I decided to let you out see if you have improved.

Why thank you Flash. <stretching> ahhh... That was a tiny and lonely
plonk hole.
That is very *something* of you, and I have been trying, lo these last
few weeks. I find that adding the odd emoticon does wonders for
conveying a gentler tone :)
See! ;-)
Of course, the pundits would say I have been "trying" for quite some
time... :-(
(OK, a little too much there, yes? It's a work in progress...)
 
R

Richard Bos

Mabden said:
Flash Gordon said:
Mabden said:
Whaaa..t? ICBR, but...What the hell would make anything beyond
arr[3] anything?!
The C standard. As it has since 1989.
That's all unitialized space.
No, the standard specified that the entire array is initialised.

I still haven't gotten my answer to how automatic vs global variables
(pointers in particular) are initialized, so I remain, as always
ignor... unenlightened.

Yes, you have. It's specified in the Standard. It's also in any of the
freely downloadable draft Standards. If you want your hand held you need
to pay us better.

Richard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,586
Members
45,086
Latest member
ChelseaAmi

Latest Threads

Top