getchar returns a different character - c

I'm trying to make a program I already made more organized by using functions. the purpose of it is processing a menu with several options for calculating different values. This code is for processing the Main menu, and the error I'm getting is that every character I type comes out as invalid (activates the default case in the switch) even if it is 1, 2 or 3, which are the possible options. What am I doing wrong?
void process_main_menu(){
int c;
print_main_menu();
int option=getchar();
while((c=getchar())!='\n' && c!=EOF);
switch(option){
case 1:
program_state=ST_MENU_BASS;
break;
case 2:
program_state=ST_MENU_TREBLE;
break;
case 3:
program_state=ST_EXIT_PROGRAM;
break;
default:
fprintf(stderr, "%s\n", MSG_INVALID_NUMBER);
program_state=ST_MAIN_MENU;
}
}
I'm updating the code as I see it wasn't complete enough. I'm actually using macros for this
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#define OPT_MENU_BASS 1
#define OPT_MENU_TREBLE 2
#define OPT_EXIT_PROGRAM 3
typedef enum {
ST_MAIN_MENU,
ST_MENU_BASS,
ST_MENU_TREBLE,
ST_EXIT_PROGRAM,
ST_MENU_TREBLE_FREQ,
ST_MENU_TREBLE_GAIN,
ST_MENU_TREBLE_FREQ_FREQ_TREBLE,
ST_MENU_TREBLE_FREQ_RESISTOR_3,
ST_MENU_TREBLE_FREQ_CAPACITOR_3,
ST_MENU_TREBLE_GAIN_RES5,
ST_MENU_BASS_FREQ,
ST_MENU_BASS_GAIN,
ST_MENU_BASS_FREQ_FREQ_BASS,
ST_MENU_BASS_FREQ_RESISTOR_2,
ST_MENU_BASS_FREQ_CAPACITOR_1,
ST_MENU_BASS_GAIN_RESISTOR_1,
} state_t;
state_t program_state;
void process_main_menu(){
int c;
print_main_menu();
char option=getchar();
while((c=getchar())!='\n' && c!=EOF);
switch(option){
case OPT_MENU_BASS:
program_state=ST_MENU_BASS;
break;
case OPT_MENU_TREBLE:
program_state=ST_MENU_TREBLE;
break;
case OPT_EXIT_PROGRAM:
program_state=ST_EXIT_PROGRAM;
break;
default:
fprintf(stderr, "%s\n", MSG_INVALID_NUMBER);
program_state=ST_MAIN_MENU;
}
}

You're reading in a character such as , which is stored as its ASCII code, not a numerical value.
You need to change your cases to look for the character '1', not the number 1.
case '1':
program_state=ST_MENU_BASS;
break;
case '2':
program_state=ST_MENU_TREBLE;
break;
case '3':
program_state=ST_EXIT_PROGRAM;
break;
EDIT:
Given the macros you're using, you need to modify the macros to represent the characters '1', '2' or '3' instead of the numbers 1, 2 or 3.
#define OPT_MENU_BASS '1'
#define OPT_MENU_TREBLE '2'
#define OPT_EXIT_PROGRAM '3'

Related

Trouble getting a switch function to loop properly

I'm writing a program to 'encrypt' an inputted string of text by using a switch statement to correlate the given character with a symbol, and output that symbol in the place of the character. I put it in a while loop, the idea being that it would loop the full switch function each time until the received character is EOF. On a guess, I believe it is looping through just the first character, because I don't advance the getchar() statement, but I'm not sure how to do that so any help would be greatly appreciated. I say this because if I use return instead of break, it closes the while loop and only takes that first letter, if I use a break then it spams the first 'encrypted' char.
#include <stdlib.h>
#include <stdio.h>
/* C program to encrypt a given text message, assuming all lowercase */
int main() {
int Input, Encrypted;
printf("Please type your message\n");
Input = getchar();
while (Input != EOF) {
switch (Input) {
case 'a':printf("!"); break;
case 'b':printf("#"); break;
case 'c':printf("#"); break;
case 'd':printf("$"); break;
case 'e':printf("%"); break;
case 'f':printf("^"); break;
case 'g':printf("&"); break;
case 'h':printf("*"); break;
case 'i':printf("`"); break;
case 'j':printf("~"); break;
case 'k':printf("-"); break;
case 'l':printf("_"); break;
case 'm':printf("="); break;
case 'n':printf("+"); break;
case 'o':printf("["); break;
case 'p':printf("{"); break;
case 'q':printf("]"); break;
case 'r':printf("}"); break;
case 's':printf(";"); break;
case 't':printf(":"); break;
case 'u':printf("|"); break;
case 'v':printf(","); break;
case 'w':printf("<"); break;
case 'x':printf("."); break;
case 'y':printf(">"); break;
case 'z':printf("'");break;
return 0;
}
}
return 0;
}
The simplest solution would be to remove the line
Input = getchar();
and to replace the line
while (Input != EOF) {
with:
while ( (Input=getchar()) != EOF && Input != '\n' ) {
Alternatively, if you find this while condition too confusing, you could also use an infinite loop, instead, like this:
#include <stdlib.h>
#include <stdio.h>
int main( void )
{
printf("Please type your message\n");
for (;;) //infinite loop, equivalent to while(true)
{
int c;
c = getchar();
if ( c == EOF || c == '\n' )
break;
switch ( c )
{
case 'a':printf("!"); break;
case 'b':printf("#"); break;
case 'c':printf("#"); break;
case 'd':printf("$"); break;
case 'e':printf("%%"); break;
case 'f':printf("^"); break;
case 'g':printf("&"); break;
case 'h':printf("*"); break;
case 'i':printf("`"); break;
case 'j':printf("~"); break;
case 'k':printf("-"); break;
case 'l':printf("_"); break;
case 'm':printf("="); break;
case 'n':printf("+"); break;
case 'o':printf("["); break;
case 'p':printf("{"); break;
case 'q':printf("]"); break;
case 'r':printf("}"); break;
case 's':printf(";"); break;
case 't':printf(":"); break;
case 'u':printf("|"); break;
case 'v':printf(","); break;
case 'w':printf("<"); break;
case 'x':printf("."); break;
case 'y':printf(">"); break;
case 'z':printf("'"); break;
}
}
return 0;
}
Note that most character sets (such as ASCII) store the characters a to z consecutively. With these character sets, you don't need the long switch statement. Instead, you can simplify it to the following:
#include <stdlib.h>
#include <stdio.h>
int main( void )
{
printf("Please type your message\n");
for (;;) //infinite loop, equivalent to while(true)
{
const char map[] = "!##$%^&*`~-_=+[{]};:|,<.>'";
int c;
c = getchar();
if ( c == EOF || c == '\n' )
break;
if ( 'a' <= c && c <= 'z' )
putchar( map[c-'a'] );
}
return 0;
}

Why is my switch case not working for multiplication or addition [duplicate]

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;
}

#default being output every time - switch case [duplicate]

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.

Switch function in C does all the cases

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;
}

How to use switch and case for strings

Based on an answer of the following question: How do I transform an IF statement with 2 variables onto a switch function using C?
I want to develop SWITCH and CASE macros to use it (like switch and case) for strings.
Some thing like that:
char buf[256];
SWITCH (buf) {
CASE ("abcdef"):
printf ("A1!\n");
BREAK;
CASE ("ghijkl"):
printf ("B1!\n");
BREAK;
DEFAULT:
printf ("D1!\n");
BREAK;
}
what could be SWITCH and CASE and BREAK and DEFAULT here ?
If you really want it, well, here it is:
#include <string.h>
#include <stdio.h>
const char *kludge;
#define evilmacro(line) label##line
#define fakelabel(line) evilmacro(line)
#define SWITCH(str) while((kludge = (str)))
#define CASE(str) if(strcmp(kludge, str) == 0) { fakelabel(__LINE__)
#define BREAK break; /* out of while loop */ }
#define DEFAULT if(1) { fakelabel(__LINE__)
int main(int argc, char *argv[]) {
SWITCH (argv[1]) {
CASE ("abcdef"):
printf ("A1!\n");
BREAK;
CASE ("ghijkl"):
printf ("B1!\n");
BREAK;
DEFAULT:
printf ("D1!\n");
BREAK;
}
return 0;
}
Getting rid of the unused labels is left as an exercise for the reader :)
EDIT: fwiw, what I would really do is table driven code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SWITCH(S) char *_S = S; if (0)
#define CASE(S) } else if (strcmp(_S, S) == 0) {switch(1) { case 1
#define BREAK }
#define DEFAULT } else {switch(1) { case 1
int main()
{
char buf[256];
printf("\nString - Enter your string: ");
scanf ("%s", buf);
SWITCH (buf) {
CASE ("abcdef"):
printf ("B1!\n");
BREAK;
CASE ("ghijkl"):
printf ("C1!\n");
BREAK;
DEFAULT:
printf ("D1!\n");
BREAK;
}
}

Resources