Reputation: 329
i've been stuck fro 6 hours at least to find ot what's wrong with my menu driven program.
Basically i made an excercise for an exam and to pass it i have to validate 2 test cases where at a specific input.txt file correspond an output.txt file
Now comes the fun part. SAME program, on Liux, with one test case it works flawessly, on the other the SAME menu code is causing never-ending menu operations like if the choice variable has always something in it. Of course on windows everything work as intended.
Anyone can help me with this? i'm getting crazy....
Edit: i run the program like this "./main < input0.txt"
It is about a library, at first you have to insert all the books and save them into a list, secondly a menu is shown asking you to search, rent or bring back a book, print the catalogue or exit if choice equals 5.
Actually the problem starts after inserting all the books into the program, the menu doesn't wait for user input and just starts to perform random actions in an infinite loop.
This is the code:
void menu(ptr head) {
//Array di funzioni per gestire le prime 4 scelte: la scelta di uscita dal programma e' gestita direttamente dal ciclo
void (*chose[4])(ptr*) = { print_catalogue, search_book, rent, bring_back };
int scelta = 0;
// for infinito per poter validare meglio l'input
for (;;) {
printf("Scegli un opzione:\n1) Stampa catalogo.\n2) Cerca.\n3) Prestito.\n4) Restituzione.\n5) Esci.\nScelta: ");
if (scanf("%d", &scelta) != 1 || scelta < 1 || scelta > 5) {
printf("Errore. Scelta non valida.\n");
// clean the buffer
scanf("%*[^\n]%*1[\n]");
}
else if (scelta == 5) { // devo uscire dell'intero programma
break;
}
else { // ho inserito un numero valido, posso procedere
// clean the buffer
scanf("%*[^\n]%*1[\n]");
(*chose[scelta - 1])(&head);
}
}
// programma terminato libero la memoria
freeList(&head);
puts("Bye");
}
i'm pretty sure with debugging that the problem is the menu...
Upvotes: 0
Views: 131
Reputation: 154174
At least these problems:
Not clearing the buffer
The following fails to consume all the text up to the '\n'
when the first character is a '\n'
.
// clean the buffer
scanf("%*[^\n]%*1[\n]"); // weak
// scanf() stop on first specifier when input is `\n`
Instead, use 2 calls
scanf("%*[^\n]");
scanf("%*1[\n]");
Missing end-of-file detection
When scanf("%d", &scelta)
returns EOF
due to end-of-file, OP's code will loop forever. @TonyB
// if (scanf("%d", &scelta) != 1 || scelta < 1 || scelta > 5) {
int cnt = scanf("%d", &scelta);
if (cnt == EOF) break;
if (cnt != 1 || scelta < 1 || scelta > 5) {
Insure output is flushed
After the print, flush - espsaily with line buffered stdout
and print does not end with '\n'
.
printf("Scegli un opzione:\n1) Stampa catalogo.\n2) Cerca.\n3) Prestito.\n4) Restituzione.\n5) Esci.\nScelta: ");
fflush(stdout); //Add
Suspicion
Problems exist in unposted print_catalogue, search_book, rent, bring_back
.
Perhaps other troubles too?
Tip: Save time. Do not use scanf()
. Usge fgets()
to read a line of input into a string and then parse with sscanf(), strtol()
etc. Much easier to handle errant input.
Upvotes: 1