Simple Option Menu (C) - c

I am trying to make a simple option menu that is executed within a do- while loop. The menu has 5 different options. I am currently trying to test the the get initial option but when I choose the case 'b' the function does not even execute and the option menu reappears again
#include "mathprogram.h"
int main (void)
{
char menu_option,initials;
int difficulty;
printf(" EDUCATIONAL MATH PROGRAM!!!\n");
printf("------------------------------------------\n\n");
do{
printf("Main Menu\n");
printf("a. Learn about how to use program.\n");
printf("b. Enter your initials (3 individual letters).\n");
printf("c. Difficulty Selection.\n");
printf("d. Start a new sequence of problems.\n");
printf("e. Save and quit.\n");
printf(" Please enter an option from the main menu: ");
scanf("%c",&menu_option);
switch(menu_option){
case 'a':
//Learn_to_use();
break;
case 'b':
initials=get_intials();
break;
case'c':
printf("case c");
//difficulty = get_difficulty();
break;
case'd':
break;
case'e':
break;
default:
printf("invalid input");
break;
}
}while(menu_option !='e');
}
get initials function:
#include "mathprogram.h"
char get_intials(void){
char initails;
printf("Please Enter Initials: ");
scanf("%c",&initails);
return initails;
}

scanf("%c", &var);
leaves the newline in the buffer or stream.
Try to change it to
scanf(" %c", &var);
and it should work as expected (Note the space before the %; this consumes the whitespace so that the next scanf call should work).
However, the initials as defined in your program consist of only one character, not three. I'll leave that up to you to design, that is a different question.

There's a '\n' between option 'b' and the initials char, the "scanf" must handle it.
Complete code that works:
#include <stdio.h>
char get_intials(void){
char initails;
printf("Please Enter Initials: ");
scanf("\n%c",&initails) ;
return initails;
}
int main (void)
{
char menu_option,initials;
int difficulty;
printf(" EDUCATIONAL MATH PROGRAM!!!\n");
printf("------------------------------------------\n\n");
do{
printf("Main Menu\n");
printf("a. Learn about how to use program.\n");
printf("b. Enter your initials (3 individual letters).\n");
printf("c. Difficulty Selection.\n");
printf("d. Start a new sequence of problems.\n");
printf("e. Save and quit.\n");
printf(" Please enter an option from the main menu: ");
scanf("%c",&menu_option);
switch(menu_option){
case 'a':
//Learn_to_use();
break;
case 'b':
initials=get_intials();
printf( "input initials:%c\n", initials) ;
break;
case'c':
printf("case c");
//difficulty = get_difficulty();
break;
case'd':
break;
case'e':
break;
default:
printf("invalid input");
break;
}
}while(menu_option !='e');
}
output:
Please enter an option from the main menu: b
Please Enter Initials: c
input initials:c

/*
This code includes a stray \n from previous input due to which get_initials method was not working properly,it picked up the remanant \n in the input stream and concluded,
flushing the input stream is the solution to the problem, uncomment the code at line 8 to get proper functionality
*/
#include <stdio.h>
char get_intials(void){
char initails;
//fflush(stdin);
printf("Please Enter Initials: ");
scanf("%c",&initails);
return initails;
}
int main (void)
{
char menu_option,initials;
int difficulty;
printf(" EDUCATIONAL MATH PROGRAM!!!\n");
printf("------------------------------------------\n\n");
do{
printf("Main Menu\n");
printf("a. Learn about how to use program.\n");
printf("b. Enter your initials (3 individual letters).\n");
printf("c. Difficulty Selection.\n");
printf("d. Start a new sequence of problems.\n");
printf("e. Save and quit.\n");
printf(" Please enter an option from the main menu: ");
fflush(stdin);
scanf("%c",&menu_option);
switch(menu_option){
case 'a':
//Learn_to_use();
break;
case 'b':
initials=get_intials();
if(initials == '\n')
printf("\n%s\n","I was there in stream as newline");
//printf("\n%c",initials);
break;
case'c':
printf("case c");
//difficulty = get_difficulty();
break;
case'd':
break;
case'e':
break;
default:
printf("invalid input");
break;
}
}while(menu_option !='e');
return 0;
}

Related

How to get a input with prompt using scanf?

I am using c and I am a newbie.
I want to get a input (1 or 2 or 3) and I will give the user suggest;
printf("please do it\n");
printf("1. \n");
printf("2. \n");
printf("3. \n");
char opt;
scanf("%c"&opt");
if opt is not 1 or 2 or 3 then
printf("error\n");
printf("please re do it");
and all is in a while(true) loop until user enter the enter(new line charactor) to exit;
and how to do it?
I tried to create a function.
void get_order(char opt){
switch(opt){
case '1':break;
case '2':break;
case '3':break;
default:
printf("error\n");
printf("please re do it"):
char option;
scanf("%c",&option);
get_order(option);
}
}
but it not work.
thank you.
That is not a good approach, your code is using recursion, it will consume memory more and more while the user don't enter the correct input. Use a loop instead. Your code should look like this:
#include <stdio.h>
int main() {
printf("please do it\n");
printf("1. \n");
printf("2. \n");
printf("3. \n");
char opt;
scanf("%c", &opt); //correct scanf
scanf("%*c"); //consume the line break
while(!(opt == '1' || opt == '2' || opt == '3')) {
printf("error\n");
printf("please re do it\n");
scanf("%c", &opt); //correct scanf
scanf("%*c"); //consume the line break
}
return 0;
}

My c program keeps crashing on as it's starting

I'm making a c program for a simple library but for some reason the program keeps crashing right on startup. Like there's a menu that is displayed but it doesn't even appear it just crashes. can any one help me?
struct library
{
char name[50];
int id;
int qty;
}books[50],copy[50],delet[50],sort[50];
int i=0;
FILE *mybooks;
int main()
{
int choice; char ans;
int id;
int qty;
int s,o=0,j=0;
char name[50];
mybooks=fopen("D:\\mybooks.txt","r");
if (mybooks == NULL) printf("Error. File not found.");
else
{
while(!feof(mybooks))
{
fscanf(mybooks,"%[^\n] %d %d",books[i].name,&books[i].id,&books[i].qty);
strcpy(copy[i].name,books[i].name);
copy[i].id=books[i].id;
copy[i].qty=books[i].qty;
i++;
}
fclose(mybooks);
}
printf("Welcome to the Library.\n");
do
{
printf("Please choose an option:\n");
printf("1.Insert a book\n");
printf("2.Delete a book\n");
printf("3.Search a book by ID\n");
printf("4.Search a book by name\n");
printf("5.Display all books (sorted by name)\n");
printf("6.Display all books (unsorted)\n");
scanf("%d",&choice);
switch (choice){
case 1:
printf("You will need to enter a name, ID, and quantity of the book.\n");
printf("please enter book name:");
fflush(stdin);
fgets(name,sizeof name,stdin);
printf("please enter book ID:");
scanf("%d",&id);
printf("please enter book quantity:");
scanf("%d",&qty);
InsertBook(name,id,qty);
printf("your book has been added successfully\n");
break;
case 2:
printf("Please enter book ID:");
scanf("%d",&id);
DeleteBook(id);
printf("book successfully deleted.\n");
break;
case 3:
printf("Please enter ID of Book:");
scanf("%d",&id);
s=LinearSearch(id,j);
if (s>=0)
{
printf("Book Found.\n");
printf("Name:%s",books[s].name);
printf("ID:%d\n",books[s].id);
printf("Quantity:%d\n",books[s].qty);
}
else
printf("Sorry, the book doesn't exist.\n");
break;
case 4:
printf("Please enter name of book:");
fflush(stdin);
gets(name);
sorting();
s=BinarySearch(name,0,i);
printf("Book Found.\n");
printf("ID:%d\n",sort[s].id);
printf("Quantity:%d\n",sort[s].qty);
break;
case 5:
sorting();
while (o<i);
{
printf("%s\n",sort[o].name);
o++;
}
printf("\n");
break;
case 6:
while(o<i)
{
printf("%s",books[o].name);
o++;
}
break;
default:
printf("Invalid Choice. Please try again.\n");
break;
}
printf("do you want to choose another option?(y/n) ");
scanf(" %c",&ans);
}while(ans == 'y');
}
(I'm using functions for the library but I don't think they are causing any problem since i didn't call them yet.)
edited the question to add the structure
You have tested an end of file condition before performing any i/o on the input file. And then, when you perform the i/o with fscanf(), you did not test the result to see if the variables were successfully read.
What is happening is that scanf() is probably failing and you do not reach the end of the loop, i.e., the EOF condition. You get stuck in there until one of your assignments (strcpy(copy[i].name,books[i].name);, copy[i].id=books[i].id; or copy[i].qty=books[i].qty;) will finally cause an overflow.
To verify this, run the code in a debugger.
Using fscanf() is very tricky, always test it thoroughly.

Prompt error when user enters a char instead of an expected int

I'm making a menu that lists options 1-3. The user is expected to enter an integer.
scanf("%d", &select_option)
How do I prompt error when user enters a char (for example "a", or "asd" for long strings, or a mixture like "1a2") instead of an expected int? Thanks.
Note: When the user enters a 'char' like 'a', 'asd', the code goes into an infinite loop for some reason.
Here's my program (minimal example):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
printf("Favourite sports? \n");
printf("1. Tennis\n");
printf("2. Badminton\n");
printf("3. Basketball\n");
printf("4. Exit program.\n");
printf("Enter your choice (1-4): ");
scanf("%d", &select_option);
while(select_option != 4)
{
switch(select_option)
{
case 1:
printf("You like tennis! Nice! \n");
break;
case 2:
printf("You like badminton! Nice!");
break;
case 3:
printf("You like basketball! Nice!");
break;
default:
system("clear");
printf("Invalid option. Please re-enter your choice (1-4).\n");
}//end switch
printf("Favourite sports? \n");
printf("1. Tennis\n");
printf("2. Badminton\n");
printf("3. Basketball\n");
printf("4. Exit program.\n");
printf("Enter your choice (1-4): ");
scanf("%d", &select_option);
}//end while
}//end main
You could do this:
#include <stdio.h>
int main(void) {
int v;
int ret = scanf("%d", &v);
if(ret == 1)
printf("OK, %d\n", v);
else
printf("Something went wrong!\n");
return 0;
}
where I took advantage of the return value of scanf(), and based on that value, I made an assumption. This will fail for the case of "1a2", but will succeed for "12" and "a".
However, this is a broad question and personally the way I would go for it is:
Use fgets() to read input.
Discard newline.
Convert string to integer (with strtol() for example).
Validate input.
I am assuming u are a beginner. You can use Switch Case which is used usually for creating menus and depending on the choice of the user executes the particular case.
I will show u a small example.
#include<stdio.h>
#include<conio.h>
int main()
{
int n;
printf("Select the sports u want to do\n");
printf("1.Tennis\n2.Karate\n3.Football\n");
scanf("%d",&n);
Switch(n)
{
case 1:printf("You chose Tennis\n");
break; //To prevent from all cases being executed we use
//break which helps from coming out of a loop
case 2:printf("You chose Karate\n");
break;
case 3:printf("You chose Football\n");
break;
default:printf("Please enter an appropriate number !");
//Cases which dont match with the input are handled by default !
}
}
Also to make the user enter input until he wants to exit add a while loop with a variable !
I hope this helps!

Why does getchar() not pause after a switch case and inside a while loop?

#include <stdio.h>
#include <stdlib.h>
main()
{
int Q = 1;
while(Q==1)
{
system("clear");
printf("MAIN MENU\n");
printf("--------------------------------------\n");
printf("1 - See all files\n");
printf("2 - See all files with permission\n");
printf("3 - VIM Editor\n");
printf("4 - EXIT\n");
fputs("Enter Choice : ",stdout);
char ch = getchar();
switch(ch)
{
case '1' : system("ls"); break;
case '2' : system("ls -l"); break;
case '3' : system("vi"); break;
case '4' : Q=0; break;
default : puts("Wrong Choice.."); break;
}
fflush(stdin);
fputs("PRESS ENTER TO CONTINUE...",stdout);
getchar();
}
}
The getchar() does not pause rather it just clears the screen and starts the menu again.
What is the cause of such problems?
I am using tutorialspoint codingground online compiler.
You could identify the problem yourself if you displayed what the unexpected character is:
default: printf ("Unrecognized choice: '%c' (%d)", ch, ch); break;
That is not a bad technique to use in any similar situation. If the code somehow gets unexpected input, say so and show what is known.
This happens because fflush() doesn't always flush the stdin and it's not the safest method to clear the buffer. Try using scanf(" %c", &yourcharvariable) instead or else you should use another getchar() to consume the '\n' left by your first input.
Try this code instead:
#include <stdio.h>
#include <stdlib.h>
main()
{
int Q = 1;
while(Q==1)
{
system("clear");
printf("MAIN MENU\n");
printf("--------------------------------------\n");
printf("1 - See all files\n");
printf("2 - See all files with permission\n");
printf("3 - VIM Editor\n");
printf("4 - EXIT\n");
fputs("Enter Choice : ",stdout);
char ch = getchar();
switch(ch)
{
case '1' : system("ls"); break;
case '2' : system("ls -l"); break;
case '3' : system("vi"); break;
case '4' : Q=0; break;
default : puts("Wrong Choice.."); break;
}
fflush(stdin); // This doesn't always work.
getchar(); // It consumes the '\n' left by your first getchar().
fputs("PRESS ENTER TO CONTINUE...",stdout);
getchar();
}
}

C program compiles in xcode, but runs infinite loop in terminal

I've been working on a group program for a systems programming class which will run functions that someone at a bank would use. These functions include add bank customers, output balance of a customer, and so on. The problem lies with the add customer function.
This function will run in an infinite loop in terminal and Putty, but when I run it as a standalone program in XCode the loop quits. Is there anything wrong with the program that I, my group members AND our professor are overlooking?
#include <stdio.h>
#include <string.h>
#include "./bank.h"
void add(FILE *fp)
{
int i=0;
char firstName[20];
char lastName[20];
float camount;
int prompt;
float samount;
float mamount;
fseek(fp,0,2);
do
{
printf("\nEnter first name: ");
scanf("%s", firstName);
strcpy(bank[i].firstName, firstName);
printf("\nEnter last name: ");
scanf("%s",lastName);
strcpy(bank[i].lastName, lastName);
printf("\nEnter checking account balance: ");
scanf("%f", &camount);
bank[i].checking = camount;
printf("\nEnter savings account balance: ");
scanf("%f", &samount);
bank[i].savings = samount;
printf("\nEnter money market account balance: ");
scanf("%f", &mamount);
bank[i].moneyMarket = mamount;
fwrite(&bank[i],1, sizeof(struct BankInfo),fp);
i++;
printf("Enter 1 to enter another name and 0 to quit: ");
scanf("%d", &prompt);
printf("%d\n", prompt);
} while(prompt == 1);
fclose(fp);
return;
}
Screenshot of output once Makefile is executed:
Sidenote: This function does write onto the file that we are passing which is great but we still need for it to break out of the loop.
EDIT: code for the main function:
#include
#include
#include
#include "bank.h"
#include "definitions.h"
int main()
{
FILE *fp;
int selection;
fp=fopen("bankInfo.dat","ab+");
selection=menu();
while(selection !=6)
{
switch(selection)
{
case 1:
add(fp);
break;
case 2:
// outputBalance(fp);
break;
case 3:
delete(fp);
break;
case 4:
update(fp);
break;
case 5:
// display(fp);
break;
case 6:
exit(0);
break;
default:
printf("Invalid selection\n");
break;
}
}
fclose(fp);
return 0;
}
You are assigning selection only once. This should fix your issue:
while(true)
{
selection=menu();
switch(selection)
{
case 1:
add(fp);
break;
case 2:
// outputBalance(fp);
break;
case 3:
delete(fp);
break;
case 4:
update(fp);
break;
case 5:
// display(fp);
break;
case 6:
fclose(fp);
exit(0);
break;
default:
printf("Invalid selection\n");
break;
}
}
return 0;

Resources