Very early on when attempting to learn programming in C, you often do exercises that read in and print out strings and numbers. Now you might assume that C has a simple function that will get user input, and indeed it does, but there are a couple of gotchas that can easily trip up those new to programming in C.
There are two things to vigorously avoid, and unfortunately they are all too commonly seen:
gets(text); /* NEVER USE gets() */
scanf("%s", text); /* MANY HIDDEN GOTCHAS */
So how do you do it right? The short answer is to use fgets to read a line of text. However, please note that when you enter text, you press the [Enter] or [Return] key and this character does not just vanish, it remains in the input buffer.
enter some text: hello world
text = "hello world
So when reading strings, you often want to remove this newline. Be careful though, because it is not always there! When the incoming text is one less than the size of the buffer, the newline is retained. You can search for the newline and overwrite it with a null terminator.
--- skimmers start here ---
fputs("enter some text: ", stdout);
if ( fgets(text, sizeof text, stdin) != NULL )
char *newline = strchr(text, '\n'); /* search for newline character */
if ( newline != NULL )
*newline = '\0'; /* overwrite trailing newline */
printf("text = \"%s\"\n", text);
enter some text: hello world
text = "hello world"
There are many other ways to do this, but this is very frequently recommended and always correct.
--- skimmers stop here ---
If you are reading a number, then first read in the input string and consequently follow it with a call to sscanf or strtol to convert it to a number.
fputs("enter some number: ", stdout);
if ( fgets(text, sizeof text, stdin) )
if ( sscanf(text, "%d", &number) == 1 )
printf("number = %d\n", number);
enter some number: 42
number = 42
The newline does not need to be removed, unless you choose to, because it is whitespace and is not part of a valid number. You may find the following related code snippets regarding the input of numbers and text useful:
To recap, here is why not to do what I said not to do! First, never use gets . It is included as a standard library function only as a holdover from pre-C89 code (the standards committee opted in the interest of not breaking existing code). But it is inherently and notoriously unsafe because there is no way to tell it the size of the buffer into which data will be read. So it is always a risk for buffer overflow , which may be used as an exploit . If you ever want to be employed as a programmer, it's best not to ever let a potential employer see you use this function!
As for scanf it is a truly complicated beast, and should certainly not be the first choice for someone just starting out programming in C. One of the first issues with scanf("%s", str); is it suffers from a very similar problem as gets , which is the incoming buffer size is not specified. If you didn't look up the description of %s you may not have known that this directive is whitespace-delimited. Which means that it if the user enters hello world , then str will be hello . There are more gotchas, such as if you are also using scanf to read integers, perhaps using scanf("%d", &i); , then the same whitespace issue may bite you. Remember that when you enter text you press the [Enter] or [Return] key and it remains in the input buffer. This can cause issues when mixed with other input functions such as getchar . There is also another insidious issue that comes up when using scanf : the "need" to flush the input buffer.
And don't think I presented a comprehensive list of gotchas associated with scanf , these were merely some common ones!
if i want to print * character insted of printing letters while scaning it from keybord just like ATM bank password application what will be code for it in C
whenever i type letter from keyboard i want to see it only *****
Or again, it is widely known by good programmers and potential employers that these are things to avoid. But if you still aren't convinced, listed below are many FAQs that say pretty much the same thing (mostly because I'm saying pretty much what they are saying).
And there is another insidious issue that comes up when using scanf: the "need" to flush the input buffer. All too often we see fflush(stdin); used to "fix" this. But actually this one problem with scanf breeds another:
Why not post this failing example so I know what you mean?
Brought up recently by tux4life and explained by Narue, the fgets/sscanf code is not bulletproof. I must admit, though, I don't quite follow this bit:
Imagine how confusing that would be to a beginner since scanf() and sscanf() are so similar.
I usually use a generously-size input buffer given by BUFSIZ (but that makes posting some input that fails more difficult). The larger input buffer tends to weed out more input issues, but again -- not bulletproof. There was a link to a snippet in which excess characters are discarded, and this could further bump up the input handling. But no doubt that brings a design decision that one could argue against.
I suppose I should also mention, since I hadn't back in the day when I could edit the snippet, that this post got quite long. I posted other snippets that went a little bit further with this -- this being an initial start and not a be-all end-all. In fact, even the other linked snippets are not bulletproof and I believe at least a few mention this explicitly.
However, please note that when you enter text, you press the [Enter] or [Return] key and this character does not just vanish, it remains in the input buffer.
That is only true when using scanf(). Both gets() nor fgets() extract the '\n' from the keyboard buffer.
The function gets() will extract the newline. You seem confused as to what both/nor mean.
It's not only true for scanf(). Many directives for scanf will leave a newline in the input stream.
It is well known that fgets() leaves the newline in the stream.
What, exactly, was your point? That you are not quite sure what you're talking about? Or that your post is confusing (a reason for bad rep, BTW)? Or that you can't be troubled to think about these things and I'm supposed to put up with erroneous comments because you haven't figured this one out yet?
You're not "defending gets()", but what is it that you are doing? Perhaps that we should prefer gets() and/or scanf() to read strings? What?
@Dave: I didn't realize I had written a malformed sentence. Thanks for pointing that out. The word "nor" should have been "and". Ok I will accept the bad rep for that confusing sentence.
Both gets() and fgets() extract the '\n' from the keyboard buffer.
>>It is well known that fgets() leaves the newline in the stream.
It MAY leave it in, only if there is not enough room in the input buffer for it. But I KNOW you know that too :) But assuming the input buffer is large enough fgets() will remove the newline from the stream, which scanf("%s") and scanf("%d") will not. I suppose that was the point of my previous post.
the 3rd example...
after trying it -i get the point that it somehow protects the code....
still dun understand the real meaning behind the codes...
fputs fflush fgets
difference between sscanf and scanf....
please enlighten me thx
I'm sure the meaning can be found
1) in your book if you have one
2) in the tutorial you are using, if you are using one
3) from GOOGLE, which knows everything and can explain stuff better than we can.