PDA

View Full Version : Learning C With XCode Issue




Darkroom
Sep 10, 2008, 05:56 AM
i'm curious about one thing. when i write this code it gives unexpected results based on the book i'm reading "The Absolute Beginner's Guide To C (1994)".


#include <stdio.h>

main ()
{
char name[5];
printf("Type Your Name: ");
scanf("%s", name);
printf("Your Name is %s", name);
return 0;
}


in the program i've entered "Geoffrey" and i'm expecting the output to be "Geof" (5 characters including the null zero), but XCode seems to ignore the array length and just prints the entire string (see attached image).

am i doing something wrong, or is the information in this book out of date?



Cromulent
Sep 10, 2008, 06:10 AM
main()
{

}


is not valid code. Use either of the following:


int main(void)
{

}


or


int main(int argc, char **argv)
{

}


As for your program you have a buffer overrun which is bad. You need to put some checking in to make sure you only read the number of bytes that the array can hold. Use fscanf() instead.

Darkroom
Sep 10, 2008, 06:11 AM
also, i've noticed that if i write this code it doesn't seem to incorporate a null zero in the array as i'll get the first 5 characters of the string, instead of the first 4 and a 5th to represent the null zero...

all this talk about null zeros...


main ()
{
char name[5] = "Geoffrey";
printf("Your Name is %s", name);
return 0;
}

Cromulent
Sep 10, 2008, 06:13 AM
char name[5] = "Geoffrey";

This won't work because Geoffrey is longer than 5 characters. Increase the size of array to handle it properly.

Darkroom
Sep 10, 2008, 06:19 AM
char name[5] = "Geoffrey";

This won't work because Geoffrey is longer than 5 characters. Increase the size of array to handle it properly.

sure, but i mean... because of this "null zero" i'm reading about that we're suppose to have enough room for in our character arrays, shouldn't the output say "Geof" and not "Geoff"?

Cromulent
Sep 10, 2008, 06:22 AM
sure, but i mean... because of this "null zero" i'm reading about that we're suppose to have enough room for in our character arrays, shouldn't the output say "Geof" and not "Geoff"?

No because C has no array boundary error checking meaning that you will actually get Geoffrey written to memory it will just overwrite stuff it has no right to touch. This is the number one cause of security issues in C code. Never ever try to put something into an array which is larger than the array itself, and also remember to make the array one larger than the string you are putting in to allow for the '\0' (null) terminating character.

Darkroom
Sep 10, 2008, 06:28 AM
No because C has no array boundary error checking meaning that you will actually get Geoffrey written to memory it will just overwrite stuff it has no right to touch. This is the number one cause of security issues in C code. Never ever try to put something into an array which is larger than the array itself, and also remember to make the array one larger than the string you are putting in to allow for the '\0' (null) terminating character.

this is what i'm saying. you see in the second program above, the variable has an array has 5 characters (which is suppose to be enough room for the null zero '\0'), but i've assigned "Geoffrey" to the variable, which is 8 characters, while the output gives me 5 characters ("Geoff") without the null zero...

if there was a null zero shouldn't it write "Geof"?

Cromulent
Sep 10, 2008, 06:30 AM
this is what i'm saying. you see in the second program above, the variable has an array has 5 characters (which is suppose to be enough room for the null zero '\0'), but i've assigned "Geoffrey" to the variable, which is 8 characters, while the output gives me 5 characters ("Geoff") without the null zero...

if there was a null zero shouldn't it write "Geof"?

Ah, good point. Sorry not paying attention.

char name[5] is actualy 6 characters long because counting starts at 0.

So 0,1,2,3,4,5 = 6 characters which answers your question.

Darkroom
Sep 10, 2008, 06:39 AM
Ah, good point. Sorry not paying attention.

char name[5] is actualy 6 characters long because counting starts at 0.

So 0,1,2,3,4,5 = 6 characters which answers your question.

that's what i am assuming... humm... this book is confusing... you see, the author talks about subscripts starting at 0, but he'll continously give "correct" examples like this:


char italCity[7] = "Verona"; /* Automatic Null Zero */


but if the subscript starts at 0, and there's a null zero automatically postfixed on that array, shouldn't this "correct" example of an array be 6 characters long instead of 7?

Cromulent
Sep 10, 2008, 06:40 AM
that's what i am assuming... humm... this book is confusing... you see, the author talks about subscripts starting at 0, but he'll continously give "correct" examples like this:


char italCity[7] = "Verona"; /* Automatic Null Zero */


but if the subscript starts at 0, and there's a null zero automatically postfixed on that array, shouldn't this "correct" example of an array be 6 characters long instead of 7?

Yes, unless he does something else with it that means it needs to be 8 characters long.

robbieduncan
Sep 10, 2008, 07:13 AM
Ah, good point. Sorry not paying attention.

char name[5] is actualy 6 characters long because counting starts at 0.

So 0,1,2,3,4,5 = 6 characters which answers your question.

Erm what? This is only true if they have redefined C since I was at Uni.


char name[5];


declares a 5 element array of characters. Valid array offests are 0,1,2,3,4. Not 5.

In the example with Verona the array must be 7 characters longs as \0 is a character.

Darkroom
Sep 10, 2008, 07:24 AM
In the example with Verona the array must be 7 characters longs as \0 is a character.

so why does


char name[5] = "Geoffrey";


output "Geoff" and not "Geof"?

see example in post #3 of this thread.

robbieduncan
Sep 10, 2008, 07:42 AM
so why does


char name[5] = "Geoffrey";


output "Geoff" and not "Geof"?

see example in post #3 of this thread.

Because the \0 is after the y. C does not automatically terminate at the length of the array with \0: it is added to the end of the string.

So "Geoffrey" is ['G','e','o','f','f','r','e','y','\0']. When you assign this to a 5 element array the first 5 elements are assigned. As you can see this will be ['G','e','o','f','f'].

As noted above C will then write ['r','e','y','\0'] into the next 4 char sized (so 8 bit) areas of memory after what you have declared. If you are lucky your program will crash. If you are unlucky some of your in-memory code will get corrupted.

Always either check your bounds or use the string copy functions to protect against this.

Cromulent
Sep 10, 2008, 07:53 AM
Erm what? This is only true if they have redefined C since I was at Uni.

Smego your right. Remember in another thread I said I still manage to make a tit out of myself by making stupid mistakes? Look no further :p.

Darkroom
Sep 10, 2008, 08:24 AM
Because the \0 is after the y. C does not automatically terminate at the length of the array with \0: it is added to the end of the string.

So "Geoffrey" is ['G','e','o','f','f','r','e','y','\0']. When you assign this to a 5 element array the first 5 elements are assigned. As you can see this will be ['G','e','o','f','f'].

As noted above C will then write ['r','e','y','\0'] into the next 4 char sized (so 8 bit) areas of memory after what you have declared. If you are lucky your program will crash. If you are unlucky some of your in-memory code will get corrupted.

Always either check your bounds or use the string copy functions to protect against this.

ok, that makes sense... thanks...

i asked because i've noticed that sometimes i can't know for sure if this book is out of date (1994) or if it's my coding that's the problem... i understand that ANSI C was updated in 2000 ("C 99" i think it's called)... i mean, even with trying to write examples from this book with gets() and puts(), the compiler tells me that gets() is not secure and will not execute properly (or at all, i forget)...

anyway, i hoping a lot of these C functions will be obsolete when i start studying C++/Objective-C.

Cromulent
Sep 10, 2008, 08:39 AM
ok, that makes sense... thanks...

i asked because i've noticed that sometimes i can't know for sure if this book is out of date (1994) or if it's my coding that's the problem... i understand that ANSI C was updated in 2000 ("C 99" i think it's called)... i mean, even with trying to write examples from this book with gets() and puts(), the compiler tells me that gets() is not secure and will not execute properly (or at all, i forget)...

anyway, i hoping a lot of these C functions will be obsolete when i start studying C++/Objective-C.

C is pretty much the same not alot changes in it. gets() is just a very bad function to use.

The best book on C (The C Programming Language 2nd Edition) was published in 1988 for example.

The major differences come from things like the main function as I pointed out in my first post and other slight differences. The C standard library is the same though. C standard library functions don't tend to become obsolete :).