Reputation: 692
Beginner's question:
Imagine this scenario: I request the user to enter an integer (getting it by using scanf) but the user enters a character; because of that the program reaches its end... but I want to overcome it, and make the program tell him that he has provided invalid input and give the user another chance to enter an input. How can I do that?
Upvotes: 6
Views: 15839
Reputation: 153303
Use fgets()
, then sscanf()
or strtol()
.
int number;
char ch;
char *Prompt2 = "":
do {
printf("%sEnter number :", Prompt2);
Prompt2 = "Invalid input\n"; // Change Prompt2
buffer char[50];
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
Handle_EOF();
}
} while (sscanf(buffer, "%d %c", &number, &ch) != 1);
Using strtol()
instead of sscanf()
adds +/- overflow protection as that sets errno
.
char *endptr;
errno = 0;
long number = strtol(buffer, &endptr, 10);
if (errno || buffer == endptr || *endptr != '\n') Handle_Error(();
See Read_long() as an example of how to use this a function.
Upvotes: 5
Reputation: 13728
Beginners work with stdio.h, which is quite OK for homework assignments, as long as you do not expect anything fancy, like password-field entry, input editing capabilities, formatting while typing, function-key and control-key handling etc. What you can do with erroneous input is limited to the basics.
If you need to write a professional application in C, which is something we used to do in the 70's and 80's, in C, you have to avoid stdio.h and hence scanf for input. You must check what your operating environment and the community have to offer. Curses, or ncurses may help you out. In MS-DOS we used to catch interrupts in order to have absolute control over the keyboard. In Unix we were using Bill Joy's termcap or a terminfo libraries, which will allow you to control your terminal and keyboard. The vi editor, as an example, was based upon termcap and curses upon terminfo.
Keep in mind that it is not a trivial task to create a crisp Text-based User Interface, nor is it easy to totally control user's input. Fortunately it is also not a problem anymore, since Java and Swing have been around...
Upvotes: 1
Reputation: 665
You could read the input from the user as a string and then use strtol()
to make it an integer.
int main(void)
{
char* end;
char number_temp[256];
int number;
while(1)
{
puts("Give a number");
scanf("%s",number_temp);
number = strtol(number_temp, &end, 10);
if (end) //If there is an error the value of *end will be non zero
printf("try again");
else
break;
}
return 0;
}
Upvotes: 0
Reputation: 21213
How about:
int n;
int c;
printf("Please enter an integer: ");
while (scanf("%d", &n) != 1) {
while (!isspace(c = getchar()));
ungetc(c, stdin);
printf("You must enter a valid number. Try again.\n");
continue;
}
Upvotes: 1
Reputation: 753455
The basic technique is to detect the problem (unexpected return value from *scanf()
), then read the rest of the line (gobble characters to newline or EOF), then resume.
Or, usually better (not least because the error reporting can report the whole line), is to use fgets()
or getline()
to read the whole line, then use sscanf()
or other techniques to parse that line, and go from there.
Upvotes: 0
Reputation: 13160
The return value of scanf
is the number of arguments successfully scanned.
Upvotes: 2