How to make a wrong user input not bug the program?

Asked

Viewed 1,562 times

5

Example, I declared the menu option as int, then the ear bug goes in there and type in a letter or a special character and this will make the program crash. The question is: is there any way to solve this?

Example:

int opc;
printf("Digite uma opção");
scanf("%d", &opc);

When the guy type letter, broken number or special character will bug.

1 answer

5


Checks the amount returned by scanf():

if (scanf("%d", &opc) != 1) /* erro */

Even better to use fgets() followed by sscanf():

char tmp[20];
if (!fgets(tmp, sizeof tmp, stdin)) /* erro */;
if (sscanf(tmp, "%d", &opc) != 1) /* erro */;

Edit

In the latter code I entered the variable tmp to have a temporary place to store the user input in characters until it becomes a number.

The fgets() reads those user characters and puts them in tmp. The amount returned by fgets() is the address of tmp, except in case of error when fgets() return NULL. Is this what the if check, if there was error during processing fgets().

if (!fgets(...)) /* ... */;
// estas duas pseudo instruções são iguais
if (fgets(...) == NULL) /* ... */;

The sscanf() works like the scanf(). The difference is in the input. The scanf() receives input from stdin (keyboard); the sscanf() receives input from a string (the string the user has written and is stored in tmp).
In either case the value that the scanf() (or sscanf()) return is the value of completed assignments, or EOF in case of error.
In our case we have only 1 possible assignment, so we have only 3 possible return values for the sscanf(). Or return 1 which means that the instruction went well he assigned the value to the variable opc; or return 0 which means that you could not assign value (for example, you typed "twenty"); or devovle EOF to indicate internal error of the function.
In other words, anything except 1 we don’t care.

int chk = sscanf(tmp, "%d", &opc);
if (chk == EOF)  /* erro interno */;
if (chk == 0) /* input com erro */;
if (chk == 1) /* tudo ok */;
  • I did not understand much, in case I would have to create a condition for if it is different from 0, 1, 2, 3, 4 and so on?

  • No, just create a condition if scanf("%d", &opc) == 1 do what you want. Two can be created with the case else to do something if the reading is not an int (in your case). This comparison with the scanf is not with the value of the item read, it is with the number of items successfully read.

  • I get it. I applied it to my software, then it even works, when I enter with a value not whole it goes to the error screen, but so it is, it did not leave her, not even with a drop asking to return to the menu screen

  • 1

    It does not exit the error because the scanf still finds the wrong value in the buffer. When you enter, for example, "X<ENTER>" for the option, the scanf sees the 'X' and indicates that Nap can convert the input to a number. How do you have him convert again, and he finds the same 'X' again wrong ... and try again and make a mistake ... ... ... If you use fgets() in a row sscanf(), like the fgets() remove both 'X' and '<ENTER>' from the buffer the problem is solved automatically.

  • Do you have to include a library? Here is the syntax error of sscanf and fgets !

  • So much sscanf() as fgets() are part of the C standard library; you do not need to do anything special about it. Prototypes are in <stdio.h>; make sure you have this header included. The syntax error can be from a previous statement ...

  • It worked, it was something else wrong here. I just didn’t quite understand the code.. If (not read integer) and If(read an integer that has a character) it would be this? what is the tmp vector? Just to understand it

  • @Leonardovilarinho added a few comments to my reply. If you need more information, ask your questions.

  • Very good, I understand, thank you there

Show 4 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.