| | |
User Input: Strings and Numbers [C]
Please support our C advertiser: Programming Forums - DaniWeb Sister Site
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:
So how do you do it right? The short answer is to use
For example:
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 ---
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
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:
As for
And don't think I presented a comprehensive list of gotchas associated with
There are two things to vigorously avoid, and unfortunately they are all too commonly seen:
c Syntax (Toggle Plain Text)
char text[20]; 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. For example:
C Syntax (Toggle Plain Text)
#include <stdio.h> int main() { char text[20]; fputs("enter some text: ", stdout); fflush(stdout); /* http://c-faq.com/stdio/fflush.html */ fgets(text, sizeof text, stdin); printf("text = \"%s\"\n", text); return 0; }
•
•
•
•
enter some text: hello world
text = "hello world
"
--- skimmers start here ---
c Syntax (Toggle Plain Text)
#include <stdio.h> #include <string.h> int main() { char text[20]; fputs("enter some text: ", stdout); fflush(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); } return 0; }
•
•
•
•
enter some text: hello world
text = "hello world"
--- 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. c Syntax (Toggle Plain Text)
#include <stdio.h> int main() { char text[20]; fputs("enter some number: ", stdout); fflush(stdout); if ( fgets(text, sizeof text, stdin) ) { int number; if ( sscanf(text, "%d", &number) == 1 ) { printf("number = %d\n", number); } } return 0; }
•
•
•
•
enter some number: 42
number = 42
- Read a Line of Text from the User
- Safe Version of gets()
- Read a Line of Text from the User, Discard Excess Characters
- Read an Integer from the User, Part 1
- Read an Integer from the User, Part 2
- Read an Integer from the User, Part 3
- Read a Floating-Point Value from the User, Part 1
- Read a Floating-Point Value from the User, Part 2
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! Last edited by niek_e; 7 Hours Ago at 3:59 am.
0
•
•
•
•
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 *****
whenever i type letter from keyboard i want to see it only *****
Last edited by ravi4mahajan; Sep 20th, 2007 at 2:05 am.
0
•
•
•
•
This question unfortunately is both frequently asked and has nothing to do with standard C.
Hopefully this may help you, though.
Hopefully this may help you, though.
0
•
•
•
•
This tutorial's original ending:
•
•
•
•
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
- http://c-faq.com/stdio/getsvsfgets.html
- http://c-faq.com/stdio/scanfprobs.html
- http://c-faq.com/stdio/scanfhang.html
- http://c-faq.com/stdio/scanfinterlace.html
- http://c-faq.com/stdio/scanfc.html
- http://c-faq.com/stdio/scanfjam.html
- http://faq.cprogramming.com/cgi-bin/...&id=1043284385
fflush(stdin);used to "fix" this. But actually this one problem withscanfbreeds another:And don't think I presented a comprehensive list of gotchas associated with
- http://c-faq.com/stdio/stdinflush.html
- http://c-faq.com/stdio/stdinflush2.html
- http://faq.cprogramming.com/cgi-bin/...&id=1043284351
- http://faq.cprogramming.com/cgi-bin/...&id=1043284392
scanf, these were merely some common ones.
0
•
•
•
•
What is missing here is an example of a text entry followed by a numeric entry. I tried to combine the code presented and should the text exceed its length of 19 and have numbers at the end, ouch!
1
•
•
•
•
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:
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.
But again, can you clarify your comment for me?
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 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.
But again, can you clarify your comment for me?
-1
•
•
•
•
what typpes of questiions in the exam if it is the subject of B.Sc(hon's) computer scienece
Similar Threads
- user input into a string (C++)
- Tutorial: User Input: Strings and Numbers [C++] (C++)
- error checking of user input (C++)
- Need Help With Error Checking User Input (C)
| Thread Tools | Search this Thread |
adobe ansi api array arrays asterisks binarysearch calculate centimeter char convert copyimagefile copypdffile cprogramme creafecopyofanytypeoffileinc createcopyoffile csyntax directory dynamic fflush file fork forloop frequency getlasterror givemetehcodez graphics gtkgcurlcompiling hacking hardware highest homework i/o inches incrementoperators infiniteloop initialization interest kernel km linked linkedlist linux linuxsegmentationfault list lists locate logical_drives match matrix microsoft motherboard multi mysql number open opendocumentformat opensource owf pattern pdf performance pointer pointers posix power problem probleminc program programming pyramidusingturboccodes radix read recursion recv repetition research scanf scheduling scripting segmentationfault send sequential shape socketprograming stack standard string strings structures systemcall testautomation turboc unix user variable voidmain() wab win32api windows.h



