Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Darkroom

Guest
Original poster
Dec 15, 2006
2,445
0
Montréal, Canada
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)".

Code:
#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?
 

Attachments

  • Picture 1.png
    Picture 1.png
    23.4 KB · Views: 49

Cromulent

macrumors 604
Oct 2, 2006
6,816
1,101
The Land of Hope and Glory
Code:
main()
{

}

is not valid code. Use either of the following:

Code:
int main(void)
{
 
}

or

Code:
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

Guest
Original poster
Dec 15, 2006
2,445
0
Montréal, Canada
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...

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

Attachments

  • Picture 3.png
    Picture 3.png
    26.1 KB · Views: 49

Darkroom

Guest
Original poster
Dec 15, 2006
2,445
0
Montréal, Canada
Code:
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

macrumors 604
Oct 2, 2006
6,816
1,101
The Land of Hope and Glory
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

Guest
Original poster
Dec 15, 2006
2,445
0
Montréal, Canada
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

macrumors 604
Oct 2, 2006
6,816
1,101
The Land of Hope and Glory
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

Guest
Original poster
Dec 15, 2006
2,445
0
Montréal, Canada
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:

Code:
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

macrumors 604
Oct 2, 2006
6,816
1,101
The Land of Hope and Glory
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:

Code:
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

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
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.

Code:
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.
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
so why does

Code:
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.
 

Darkroom

Guest
Original poster
Dec 15, 2006
2,445
0
Montréal, Canada
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

macrumors 604
Oct 2, 2006
6,816
1,101
The Land of Hope and Glory
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 :).
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.