A char
object can only hold a single character value. To store a string, you need to use an array of char
1:
#define MAX_NAME_LENGTH 20 // or whatever
...
char name[MAX_NAME_LENGTH+1]; // +1 for string terminator
Remember that in C, a string is a sequence of character values including a 0-valued terminator - for example, the string "hello"
is represented as the character sequence {'h', 'e', 'l', 'l', 'o', 0 }
. So your array needs to be large enough to handle the longest string you expect plus an extra element for the 0 terminator. If you expect your largest string to be 20 characters long, then the array needs to be able to hold at least 21 characters.
For various historical reasons not worth going into right now, C I/O routines won't protect you if you try to write more characters to the array than it's sized to hold. If name
is sized to hold 20 characters plus the 0 terminator, and you read it as
scanf( "%s", name );
if someone enters 200 characters, then 180 characters will be written to the memory immediately following the name
array, potentially leading to all kinds of mayhem. Buffer overflows are a popular malware exploit, so it's a security issue as well.
To protect against that, you need to specify the max number of characters to read. Unfortunately, scanf
requires you to hardcode it as part of the conversion specifier, rather than providing it as a separate argument like printf
. You can't just use the macro like
scanf( "%MAX_NAME_LENs", name );
you either have to specify it as a numeric literal:
scanf( "%20s", name );
or use some preprocessor trickery to expand the macro and concatenate it with the format string:
#define EXPAND(x) #x
#define STR(x) EXPAND(x)
...
scanf( "%" STR(MAX_NAME_LEN) "s", name );
Ater preprocessing, that expands to
scanf( "%" "20" "s", name );
which is evaluated as
scanf( "%20s", name );
Or, you could go the easy route and use fgets
:
fgets( name, sizeof name, stdin );
which is what I recommend.
- Or
wchar_t
for "wide" strings, which you don't need to worry about right now.