This question already has an answer here:
Switch statement always including both the case and default
(1 answer)
Closed 5 years ago.
In the code below, no matter what I input, it always outputs the corresponding case statement WITH a default case statement! But when I removed the while(1){} loop, everything works fine. Why is this happening? loop's(same for for(;;) loop) fault or default case's fault? How can I change the code to print correctly within a loop?
#include <stdio.h>
#include <ctype.h>
#include <conio.h>
int main(){
char ch;
puts("Client Management System");
puts("========================");
puts("A: add task");
puts("D: delete task");
puts("U: modify task");
puts("Q: quit system");
while(1){
ch = getchar();
ch = toupper(ch);
switch(ch){
case 'A':
puts("adding task......");
break;
case 'D':
puts("deleting task......");
break;
case 'U':
puts("modifying task......");
break;
case 'Q':
return 0;
default:
puts("invalid option");
}
}
return 0;
}
Additional case needs to be added to handle '\n' condition. This is because when you type a case in the console and press enter key, '\n' also be included. So handling this would eliminate the default case execution.
Related
Okay so I'm writing a code for something and I've encountered a problem whilst testing switch function. It does all the cases incrementing from one's selection (my explanation). Could someone help me explain why is this so?
#include <stdio.h>
#include <stdlib.h>
#include "ratedzfunctions.h"
int main()
{
int selection, loop=1;
FILE* fajl;
//Opening the participants file
fajl=fopen("participants.txt","r+");
if (fajl==NULL)
{
printf("The file cannot be opened.\n");
}
//MENU
do
{
printf("\nMENU: \n------------\n1. RATEDZ\n\n2. STATISTICS\n\n3. EXIT\n\n==>");
scanf("%d", &selection);
switch (selection)
{
case 1:
ratedz(fajl);
case 2:
stats(fajl);
case 3:
loop=0;
}
}
while (loop==1);
fclose(fajl);
return 0;
}
//THIS IS FROM RATEDZFUNCTIONS.H
void ratedz(FILE *fajl)
{
printf("\nTEST RATEDZ");
}
void stats(FILE *fajl)
{
//Printing all participants
char *buffer=(char*) malloc(50);
while(fscanf(fajl,"%s %s %s", buffer)!=EOF)
{
printf("\n%s %s %s", buffer);
}
free(buffer);
}
You forgot to add a break; statement after each case.
case 2:
stats(fajl);
break; /* <---- */
You should put a break; after each case.
The switch/case rule is easy, after a mached case, all following cases will be executed until a break; or end of switch:
switch (selection)
{
case 1:
...
break;
case 2:
...
break;
case 3:
...
break; // Last break is not necessary
// but it's good practice to put it.
}
There are good situations which removing break; is reasonable:
switch(letter)
{
case 'i':
case 'a':
case 'o':
case 'u':
case 'e':
printf ("Vowel!");
break;
default :
printf ("Consonant!");
break;
}
If you do not add a break at the end of each case it will just fall through to the next case:
switch (selection)
{
case 1:
ratedz(fajl);
break ;
case 2:
stats(fajl);
break ;
/* ... */
}
A case in a switch statement is treated like a label (see C.11 § 6.8.1). . There is actually no requirement to have any cases at all (See C.11 § 6.8.4).
switch (0) { /* do nothing */ }
The above code will compile just fine.
Since a case is like a label, there are no implicit semantics attached to it that would cause it to automatically jump outside the switch. Just as break is used to leave a loop block early, break is also used to leave a switch block early.
Syntax for switch staement in C
switch(expression)
{
case (constant-expression) : staements
....
case (constant-expression) : staements
default : statements
}
To work with a particular case your last statement in that group of statement must be break.
Without the break statement , when the last statement in the case has been executed, control "falls through" to the first statement in the following case; the case label (const-expression) for the next case is ignored. Without break (or some jump statement), control will flow from one case into the next.
Some corrections,
#include <stdio.h>
#include <stdlib.h>
#include "ratedzfunctions.h"
int main()
{
int selection, loop=1;
FILE* fajl;
//Opening the participants file
fajl=fopen("participants.txt","r+");
if (fajl==NULL)
{
printf("The file cannot be opened.\n");
exit(1); //handle error when file cannot be opened...
}
//MENU
do
{
printf("\nMENU: \n------------\n1. RATEDZ\n\n2. STATISTICS\n\n3. EXIT\n\n==>");
scanf("%d", &selection);
switch (selection)
{
case 1:
ratedz(fajl);
break;
case 2:
stats(fajl);
break;
case 3:
loop=0;
break;
default:
break;
}
}
while (loop==1)
{
//do stuff here
}
fclose(fajl);
return 0;
}
I have a question about a thingy I need to do in my code,
I need to pause the code before it ends, for example there's a switch case
for
1-etc
2-etc
3
.
.
5-etc
when i click 9 for instance,the output is
printf("This option is unknown.\nThe program exits.\n");
now what I need to do : Is after this massage the program needs to stop and when I press "enter" it will continue to "press any key to continue",
would very much appreciate the help.
EDIT: ` default:
printf("This option is unknown.\nThe program exits.\n");
getchar();
system("pause");
break;`
Try system("PAUSE"). Library needed: stdlib.h
You did not show the actual code, so it's tough saying what's actually going on there, but I'll assume your function calls an exit().
You need to add some code which waits for user input, before the control reaches the exit(). An example, getchar(), will just do the job for you.
Before you call for the exit() (or a return), you need to add
while ('\n' != getchar()); //rough way to clean input buffer
puts("press any key to continue"); //print message
getchar(); //wait for any new key press
I am very curious about your final code which resolved this issue.
I wrote a sample code that kind of mimic your situation.
Please take a look at the following code and let me know if this is what you did to fix this problem. Thanks
#include <stdio.h>
#include <string.h>
int
main(void)
{
char ch;
printf("Please enter an option [1,2,3,4,5 (return to exit):");
while( ( ch = getchar() ) !='\n' )
{
switch(ch)
{
case '1':
printf("hello 1\n");
break;
case '2':
printf("hello 2\n");
break;
case '3':
printf("hello 3\n");
break;
case '4':
printf("hello 4\n");
break;
case '5':
printf("hello 5\n");
break;
default:
printf("unknown option. Press a key to continue. (return to exit)\n");
break;
}
printf("Please enter an option [1,2,3,4,5 (return to exit):");
ch = getchar();
}
return 0;
}
Okay so I'm writing a code for something and I've encountered a problem whilst testing switch function. It does all the cases incrementing from one's selection (my explanation). Could someone help me explain why is this so?
#include <stdio.h>
#include <stdlib.h>
#include "ratedzfunctions.h"
int main()
{
int selection, loop=1;
FILE* fajl;
//Opening the participants file
fajl=fopen("participants.txt","r+");
if (fajl==NULL)
{
printf("The file cannot be opened.\n");
}
//MENU
do
{
printf("\nMENU: \n------------\n1. RATEDZ\n\n2. STATISTICS\n\n3. EXIT\n\n==>");
scanf("%d", &selection);
switch (selection)
{
case 1:
ratedz(fajl);
case 2:
stats(fajl);
case 3:
loop=0;
}
}
while (loop==1);
fclose(fajl);
return 0;
}
//THIS IS FROM RATEDZFUNCTIONS.H
void ratedz(FILE *fajl)
{
printf("\nTEST RATEDZ");
}
void stats(FILE *fajl)
{
//Printing all participants
char *buffer=(char*) malloc(50);
while(fscanf(fajl,"%s %s %s", buffer)!=EOF)
{
printf("\n%s %s %s", buffer);
}
free(buffer);
}
You forgot to add a break; statement after each case.
case 2:
stats(fajl);
break; /* <---- */
You should put a break; after each case.
The switch/case rule is easy, after a mached case, all following cases will be executed until a break; or end of switch:
switch (selection)
{
case 1:
...
break;
case 2:
...
break;
case 3:
...
break; // Last break is not necessary
// but it's good practice to put it.
}
There are good situations which removing break; is reasonable:
switch(letter)
{
case 'i':
case 'a':
case 'o':
case 'u':
case 'e':
printf ("Vowel!");
break;
default :
printf ("Consonant!");
break;
}
If you do not add a break at the end of each case it will just fall through to the next case:
switch (selection)
{
case 1:
ratedz(fajl);
break ;
case 2:
stats(fajl);
break ;
/* ... */
}
A case in a switch statement is treated like a label (see C.11 § 6.8.1). . There is actually no requirement to have any cases at all (See C.11 § 6.8.4).
switch (0) { /* do nothing */ }
The above code will compile just fine.
Since a case is like a label, there are no implicit semantics attached to it that would cause it to automatically jump outside the switch. Just as break is used to leave a loop block early, break is also used to leave a switch block early.
Syntax for switch staement in C
switch(expression)
{
case (constant-expression) : staements
....
case (constant-expression) : staements
default : statements
}
To work with a particular case your last statement in that group of statement must be break.
Without the break statement , when the last statement in the case has been executed, control "falls through" to the first statement in the following case; the case label (const-expression) for the next case is ignored. Without break (or some jump statement), control will flow from one case into the next.
Some corrections,
#include <stdio.h>
#include <stdlib.h>
#include "ratedzfunctions.h"
int main()
{
int selection, loop=1;
FILE* fajl;
//Opening the participants file
fajl=fopen("participants.txt","r+");
if (fajl==NULL)
{
printf("The file cannot be opened.\n");
exit(1); //handle error when file cannot be opened...
}
//MENU
do
{
printf("\nMENU: \n------------\n1. RATEDZ\n\n2. STATISTICS\n\n3. EXIT\n\n==>");
scanf("%d", &selection);
switch (selection)
{
case 1:
ratedz(fajl);
break;
case 2:
stats(fajl);
break;
case 3:
loop=0;
break;
default:
break;
}
}
while (loop==1)
{
//do stuff here
}
fclose(fajl);
return 0;
}
In the following piece of code what is while loop doing (marked with "loop")?:-
int main(void)
{
char code;
for (;;)
{
printf("Enter operation code: ");
scanf(" %c", &code);
while (getchar() != '\n') // loop
;
switch (code)
{
case 'i':
insert();
break;
case 's':
search();
break;
case 'u':
update();
break;
case 'p':
print();
break;
case 'q':
return 0;
default:
printf("Illegal code\n");
}
printf("\n");
}
}
Diclaimer:The code is not complete, it's just a part of the code because of which it won't compile.
getchar() used here to eat up the extra characters entered by user and the newline character \n.
Suppose a user entered the operation code as
isupq\n // '\n' is for "Enter" button
then, scanf() would read only character i and rest of the five characters would become consumed by the statement
while (getchar() != '\n')
;
Thus for next iteration scanf() will wait for user to input a character instead of reading it from the input buffer.
while (getchar() != '\n') // loop
;
is here to clean the buffer.
The problem that this while solves is that scanf(" %c", &code); only grabs a single character from the input buffer. This would be fine, except that there's still a newline left in the input buffer that resulted from hitting 'enter' after your input. a buffer clear is needed for the input buffer. that's what the while loop does
it is a common problem with c
Here application waits for the user to press enter.
Since the for loop in the given code is a infinite looping so the while loop is checking whether the input character is \n or not. In case the the character entered is \n it then moves toward the switch case. In general sense it is waiting of return key to be pressed to confirm your input.
if you use the fgetc function you don't have to worry and check for the enter key in your infinite loop. Even if you enter more than one character it will only take the first one
int main(void)
{
char code;
for (;;)
{
printf("Enter operation code: ");
code = fgetc(stdin);
switch (code)
{
case 'i':
insert();
break;
case 's':
search();
break;
case 'u':
update();
break;
case 'p':
print();
break;
case 'q':
return 0;
default:
printf("Illegal code\n");
}
printf("\n");
}
}
scanf() usually is not a good way to scan char variables, because the Enter you press after entering the character remains in input buffer. Next time you call scanf("%c", &input) this Enter already present in buffer gets read & assigned to input, thus skipping next input from user.
I'm trying to implement a command line menu in C so that when the user enters a character, it will instantly process the character and carry out specific functions. The problem is, whenever I try to make it so that after each input is processed, the menu displays again and is ready for new input, the program will just continually read input and never process it unless I exit the program.
This is the code that works 1 time through:
char command;
command = getchar();
switch(command){
case 'c':
//create a new hash table;
break;
case 'l':
//look up a word;
break;
case 'f':
//read a file
break;
case 'p':
//print the table;
break;
case 'r':
//Remove a word
break;
case 'q':
exit(0);
break;
}
However, if I try to place it into an infinite loop to continually run, like I said, it will never process the inputs until I exit the program.
This code should work for you — it works for me. Note the use of int for the variable command.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(void)
{
int command;
while ((command = getchar()) != EOF)
{
switch(command)
{
case 'c':
printf("Create a new hash table\n");
break;
case 'l':
printf("Look up a word\n");
break;
case 'f':
printf("Read a file\n");
break;
case 'p':
printf("Print the table\n");
break;
case 'r':
printf("Remove a word\n");
break;
case 'q':
printf("Quit\n");
exit(0);
break;
default:
printf("Unexpected input %d (0x%.2X) ('%c')\n",
command, command, isgraph(command) ? command : '.');
break;
}
}
return 0;
}