Archived

This topic is now archived and is closed to further replies.

Ex-RoNiN

Failsafe's against wrong input in C

Recommended Posts

Ex-RoNiN    122
Right, I have a program involving several functions in a program, some of which require input. However, as we all know the program tends to crash if something wrong is put in (char instead of int for example). Most of the functions look like this: { int x=0; printf ("instructions\n"); scanf ("%d", &x); switch (x) { case 0: printf("blabla"); break; case 1: printf("blabla"); break; } return y; } Now, the weak point is obviously the scanf. If a char is input, or a number greater than 1, the whole thing is gonna get messed up. So I thought I would do something like this: { start: int x=0; printf("instruction"); if (scanf ("%d", &x)==1) { switch (x) { case 0: bla bla; break; case 1: bla bla; break; } return y; } else goto start; } But this ends up in an infinite loop thing? Why? Assuming a wrong input was given (ie scanf was unsuccesful and hence its value remains 0), then the else is going to make the function run again from the declaration that x=0 (hence getting rid of the previous input) and it should then continue with printing the instructions again and running scanf. But it doesnt, it goes into a loop. What am I doing wrong?

Share this post


Link to post
Share on other sites
Oluseyi    2103
if (scanf ("%d", &x)==1) 

scanf returns the number of fields converted and assigned. Since that value isn''t critical, simply do the following:
while( !scanf( "%d", &x ) ) 

It also eliminates the goto and makes for "cleaner" logic.

To check whether the input is appropriate, use one of the isalpha, isdigit and isalphanum functions/macros.

[ GDNet Start Here | GDNet Search Tool | GDNet FAQ ]
[ MS RTFM [MSDN] | SGI STL Docs | Boost ]
[ Google! | Asking Smart Questions | Jargon File ]
Thanks to Kylotan for the idea!

Share this post


Link to post
Share on other sites
bishop_pass    109
If you want failsafe, don''t use scanf(). I believe scanf() was for programmers to create code for programmers. It''s a quick and dirty solution to get code tested quickly. In that respect, scanf is great. But I would never use it in a robust application.


  
int getInput (char *buffer, int maxlen)
{
int i = 0;
int ch;

/* Read in single line from "stdin": */
while ((ch = getchar()) != ''\r'') {
buffer[i++] = (char) ch;
if (i > (maxlen - 1))
i = maxlen - 1;
}
buffer[i] = ''\0'';

return i;
}


The above code will read in any amount of characters until the return key is pressed, but never overflow your buffer.

If you''re only looking for one number, strip the leading whitespace. Strip the trailing whitespace. Check to make sure all of the characters inbetween conform to what you are looking for, and then parse the data.

Anyway, for your needs, do something like this:


  
while (1) {
// get your input here

...
// parse your input here


// now exit the loop if the input is good

if (selection == 1 || selection == 2 || selection == 3)
break;
}

Share this post


Link to post
Share on other sites
Beer Hunter    712
I can write that function in one line, although it keeps the newline character:

int getInput (char *buffer, int maxlen) {
return fgets(buffer, maxlen, stdin);
}


For reading c-strings, I don''t recommend scanf. For everything else, why not? Check the return value if you want to be sure.

Share this post


Link to post
Share on other sites