When we define a character array as 'char name[10]', this indicate that the array 'name' can hold a string of length ten character. But in the program shown below the array name can hold more than ten characters. How is this possible?
//print the name of a person.
char name[10];
scanf("%s",name);
printf("%s",name);
Here if I enter a name even of length greater than ten character, there is no run time error and the program prints all the characters I have entered. There is a program termination if I enter the name of twenty or more characters.
Note: I am running the program on Ubuntu9.04 using a gcc compiler.
Because scanf doesn't know how long the array is. The variable "name" is not of type "array" but of type "pointer" (or "address"). It says, start writing here and keep writing until you're done. You may be lucky and have some other not-as-critical stuff on your stack that gets overwritten, but eventually, scanf will write and write and overwrite something fatal, and you'll get a Segmentation Fault. That's why you must always pass the size of arrays around.
It's akin to giving a blind person a pencil and saying "start writing here", without them being able to see where the end of the paper is. They will eventually write on the table and damage something. (Note: this is not a knock on the blind, this is just a metaphor.)
In the above case, I highly recommend using fgets() to grab a specific amount from stdin, and then sscanf() to pull whatever information from that line and put it into separate variables as needed. Scanf() and fscanf() are evil, I have never found a use for them that fgets()+sscanf() can't more safely solve.
char line[1024]; /* arbitrary size */
if( fgets( line, 1024, stdin ) != NULL )
{
fprintf( stdout, "Got line: %s", line );
}
Or for things beyond strings:
# cat foo.c
#include <stdio.h>
int main( int argc, char **argv )
{
int i;
char line[1024];
while( fgets( line, 1024, stdin ) != NULL )
{
if( sscanf( line, "%d", &i ) == 1 )
{ /* 1 is the number of variables filled successfully */
fprintf( stdout, "you typed a number: %d\n", i );
}
}
}
# gcc foo.c -o foo
# ./foo
bar
2
you typed a number: 2
33
you typed a number: 33
<CTRL-D>
With an array of size 10 chars, to represent a string in C You can really only use 9 characters and the null terminated character. If you use more than 9 characters (+1 termination) then you'll have undefined behavior.
You are simply overwriting memory that you shouldn't be. What happens whether segfault, or working as you expect is as good as random.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With