Command Line Menu in C - c

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

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

Switch / Case issue

For C language, I know I'm close, but for for any character inputted, the printout is "Consonant". What is wrong with my switch case statement. Will I need if statements?
#include <stdio.h>
#include <stdlib.h>
int main()
{
char name;
printf("Enter a character: ");
scanf_s("%c", &name);
switch (name)
{
case 'a':
printf("Vowel");
break;
case 'e':
printf("Vowel");
break;
case 'i':
printf("Vowel");
break;
case 'o':
printf("Vowel");
break;
case'u':
printf("Vowel");
break;
case 'y':
printf("Sometimes");
break;
default:
printf("Consonant");
}
return 0;
}
Note that the Microsoft page for scanf_s() says:
In the case of characters, a single character may be read as follows:
char c;
scanf_s("%c", &c, 1);
Your scanf_s() call is failing, but you are not checking the result, so you don't know that.
ALWAYS check the result of input functions!
And make sure you've read the manual page for functions you're using.
It's probably also a good idea to use " %c" as the format string to skip white space. However, that's a refinement for later.
You don't have a break; after the code in the default: case label. That's not a good idea.
You can use:
if (scanf_s("%c", &name, 1) == 1)
{
switch (name)
{
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
printf("Vowel\n");
break;
case 'y':
printf("Sometimes\n");
break;
default:
printf("Consonant\n");
break;
}
}
else
fprintf(stderr, "Failed to read a character\n");
Note that all upper-case letters, punctuation, white space and control characters are deemed to be consonants. That's not entirely accurate.

Why does getchar() read an entire line?

The sample of the program is as follow:
int main(void)
{
char input;
printf("\nEnter phone number: ");
while ((input = getchar()) != '\n') {
switch (toupper(input)) {
case 'A': case 'B': case 'C':
printf("2");
break;
case 'D': case 'E': case 'F':
printf("3");
break;
case 'G': case 'H': case 'I':
printf("4");
break;
case 'J': case 'K': case 'L':
printf("5");
break;
case 'M': case 'N': case 'O':
printf("6");
break;
case 'P': case 'R': case 'S':
printf("7");
break;
case 'T': case 'U': case 'V':
printf("8");
break;
case 'W': case 'X': case 'Y':
printf("9");
break;
default:
putchar(input);
}
}
printf("\n\n");
return 0;
}
My question is, how on Earth does the flow here work? I can't seem to understand the path the program took. Does the char variable magically become an array? How is it that putchar() prints the entire line instead of the first character entered? How exactly does something that's supposed to get and print one character, reads and prints an entire line of characters while altering them with the switch statement? Does it test each char as its entered? But then how is the string printed as a string?
Edit: I've done some research and I read about a keyboard buffer, which seems to be the cause of my confusion. To my knowledge, getchar() and putchar() receives and outputs a single character. I'm aware that the loop asks continuously for the next "buffered" char when the getchar() comes back around, still a bit confused by I should get it, but what's more confusing is putchar(). At the end of the loop, when it breaks and goes to the condition, does it print that one character then continues and prints the other one by one with each execution of the loop? Only stopping the loop at which point the new line was read? And if so, only what was previously printed, is displayed on the screen? And then if that's the case then the printed chars would print in line next to each other with each execution, giving the illusion of a string? I need confirmation on this and also, when is the char discarded and replaced? After its printed? And at which line does it receive the next char in the buffer queue?

How to do another calculation without exiting black screen?

Here is my code : a switch statement
#include <stdio.h>
#include <conio.h>
void main()
{
float a,b,ans;
int code;
printf("enter two no\n");
scanf("%f%f",&a,&b);
printf("select an expression \n1-addition \n2-substraction \n3multiplication \n4-divide\n ");
scanf("%d",&code);
switch(code)
{
case 1:ans=a+b;
printf("%f\n",ans);
break;
case 2:ans=a-b;
printf("%f\n",ans);
break;
case 3:ans=a*b;
printf("%f\n",ans);
break;
case 4:ans=a/b;
printf("%f\n",ans);
break;
}
getch();
}
Now after doing one calculation lets say 1-addition I want to again do another calculation without exiting the black screen.
how it can be done?
if I have to put a loop then where and how, please explain.
Following code will do the all operation for the given input till you choose to exit. But if you want to do the operation for different values the you can include the 7th and 8th line inside the while loop.
#include <stdio.h>
#include <conio.h>
void main()
{
float a,b,ans;
int code;
printf("enter two no\n");
scanf("%f%f",&a,&b);
while(1)
{
printf("select an expression \n1-addition \n2-substraction \n3multiplication \n4-divide \n5-Exit\n");
scanf("%d",&code);
switch(code)
{
case 1:
ans=a+b;
printf("%f\n",ans);
break;
case 2:
ans=a-b;
printf("%f\n",ans);
break;
case 3:
ans=a*b;
printf("%f\n",ans);
break;
case 4:
ans=a/b;
printf("%f\n",ans);
break;
}
if(code == 5)
return;
}
getch();
}
while(1){
printf("Press 0 to exit");
switch(code)
{
case 1:ans=a+b;
printf("%f\n",ans);
break;
case 2:ans=a-b;
printf("%f\n",ans);
break;
case 3:ans=a*b;
printf("%f\n",ans);
break;
case 4:ans=a/b;
printf("%f\n",ans);
case 0:
exit();
break;
}
}

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

Resources