I have a program that involves a menu from which the user can select various options. The selection is handled by a scanf("%d")
.
#include <stdio.h>
int menu();
int main
{
int sel;
do
{
sel = menu ();
} while (sel != 0);
return 0;
}
int menu ()
{
int menuSelect;
do
{
printf(" ------------------Menu------------------\n");
printf("| 1) Nuova partita |\n");
printf("| 2) Inserisci valori |\n");
printf("| 3) Cancella valori |\n");
printf("| 4) Verifica la soluzione attuale |\n");
printf("| 5) Carica e verifica una soluzione |\n");
printf("| 6) Riavvia la partita attuale |\n");
printf("| 0) Esci |\n");
printf(" ----------------------------------------\n");
printf("=> ");
scanf("%d", &menuSelect);
} while (menuSelect < 0 || menuSelect > 6)
/*
various cases
*/
return menuSelect;
}
When passing an int
as input it work fine.
But if I pass something else, it turns into an infinite loop. For example:
input:
a
output:
------------------Menu------------------
| 1) Nuova partita |
| 2) Inserisci valori |
| 3) Cancella valori |
| 4) Verifica la soluzione attuale |
| 5) Carica e verifica una soluzione |
| 6) Riavvia la partita attuale |
| 0) Esci |
----------------------------------------
=>
------------------Menu------------------
| 1) Nuova partita |
| 2) Inserisci valori |
| 3) Cancella valori |
| 4) Verifica la soluzione attuale |
| 5) Carica e verifica una soluzione |
| 6) Riavvia la partita attuale |
| 0) Esci |
----------------------------------------
=>
------------------Menu------------------
| 1) Nuova partita |
| 2) Inserisci valori |
| 3) Cancella valori |
| 4) Verifica la soluzione attuale |
| 5) Carica e verifica una soluzione |
| 6) Riavvia la partita attuale |
| 0) Esci |
----------------------------------------
=>
etc...
I would have thought that a char
would just get ignored by scanf("%d")
, is the creation of the infinite loop caused by the scanf
receiving incompatible input or is it something to do with my program?
Is there also some way to avoid this happening?
CodePudding user response:
By typing a
when an int was expected, nothing was scanned into menuSelect
. It remains an uninitialized variable, invoking undefined behavior.
You can check the return value of scanf
and use that to determine whether to continue or not. If scan_result
is not 1
, then it did not read into menuSelect
.
int scan_result = scanf("%d", &menuSelect);
} while (scan_result != 1 || menuSelect < 0 || menuSelect > 6);
A very simple program can show you what's happening:
#include <stdio.h>
int main(void) {
int n;
int result = scanf("%d", &n);
printf("%d\n", result);
}
$ ./a.out
6
1
$ ./a.out
a
0
$
CodePudding user response:
I think that if scanf
input is incorrect, it gets stuck inside input buffer indefinitely. You may try to read it with a string after each erroneous scanf()
.
if (scanf("%d", &menuSelect) == 0){
char tmp[20];
scanf("%s", tmp);
menuSelect = 0;
}