Breaking Case with certain responses - c

I am creating a little scoring program and am having trouble with this case. When I enter an 'e', it breaks correctly as the default suggests, but then it runs through the first switch statement, and then exits the program..
This only happens when I enter the letter 'e'. If i enter 'q' or anything else, it doesnt exit ?
case 'd': // Field Competition Logs
{
int fieldRound;
int ifaaField[2], ifaaFieldTotal;
int ifaaHunter[2], ifaaHunterTotal;
int fitaField[1];
int field3D[1];
printf ("Please select the type of round you shot\n\n");
printf ("\t(a) IFAA Field\n\t(b) IFAA Hunter\n\t(c) Fita Field\n\t(d) 3D Field\n> ");
scanf (" %d", &fieldRound);
switch (fieldRound)
{
case 'a': // Ifaa Field Round
{
printf ("Please enter the score for your first round > ");
scanf (" %d", &ifaaField[0]);
printf ("Please enter the score for your second round > ");
scanf (" %d", &ifaaField[1]);
ifaaFieldTotal = ifaaField[0] + ifaaField[1];
printf ("Total of your first half (%d) and your second half (%d) is %d", ifaaField[0], ifaaField[1], ifaaFieldTotal);
break;
}
case 'b': // Ifaa Hunter Round
{
printf ("Please enter the score for your first round > ");
scanf (" %d", &ifaaHunter[0]);
printf ("Please enter the score for your second round > ");
scanf (" %d", &ifaaHunter[1]);
ifaaHunterTotal = ifaaHunter[0] + ifaaHunter[1];
printf ("Total of your first half (%d) and your second half (%d) is %d", ifaaHunter[0], ifaaHunter[1], ifaaHunterTotal);
break;
}
case 'c': // Fita Field Round
{
printf ("Please enter your Fita Field score > ");
scanf (" %d", &fitaField[0]);
printf ("Total of your Fita Field round is %d", fitaField[0]);
break;
}
case 'd': // Field 3D Round
{
printf ("Please enter your 3D Field score > ");
scanf (" %d", &field3D[0]);
printf ("Total of your 3D Field round is %d", field3D[0]);
break;
}
default:
printf ("Please enter a valid response");
break;
}
break; // Breaks out of Case D
}
case 'e': // Exits the program
{
printf ("Thank you, Good bye!\n");
return 0;
}
OUTPUT
Please select the type of round you shot
(a) IFAA Field
(b) IFAA Hunter
(c) Fita Field
(d) 3D Field
> e
Please enter a valid response
Hi s. c, Please choose from the following options by typing the letter and pressing the 'return' key
(a) Enter Scored Practice logs
(b) Enter Practice Arrow count
(c) Enter Competition logs
(d) Enter Field Competition Logs
(e) Exit Program
> Thank you, Good bye!

scanf (" %d", &fieldRound);
This scanf fails! It expects numeric input, not an alphabetic character!

Change
scanf (" %d", &fieldRound);
to
scanf (" %c", &fieldRound);
In your current configuration, your scanf expects a decimal number, not a character. It thusly fails if you try inputting a character.
Additionally, you need to change int fieldRound; to char fieldRound;.

Related

How to make this program ask for input again if invalid input is entered (in C programming)? [duplicate]

This question already has answers here:
Why is scanf() causing infinite loop in this code?
(16 answers)
Closed 5 years ago.
There are two different spots where the check happens.
That is, where you enter a, s, m, d, or q and when you enter the first and second number.
At any of the checks, if the check is false, it should ask you to re-enter your input.
I'm guessing this can be done by putting a scanf statement for the numbers part inside a while loop check, but when I enter an invalid value (non-number) the loop runs infinitely.
So I must be doing something wrong. I have made the a, s, m, d, and q part work for the most part.
But the second part never seems to work. For this, I left my failed attempts at the while loops out, and instead in //comments.
Any help would be greatly appreciated!
Here is my code so far:
#include <stdio.h>
#include <ctype.h>
int main(void)
{
char ch;
float num1,num2,answer;
printf("Enter the operation of your choice:\n");
printf("a. add s. subtract\n");
printf("m. multiply q. divide\n");
printf("q. quit\n");
while ((ch = getchar())!='q')
{
printf("Enter the operation of your choice:\n");
printf("a. add s. subtract\n");
printf("m. multiply q. divide\n");
printf("q. quit\n");
ch=tolower(ch);
if (ch=='\n')
continue;
else
{
switch(ch)
{
case 'a':
//The code below is what I have tried to make work.
//This code would also be copy pasted to the other cases,
//of course with the correct operations respectively being used.
//
//printf("Enter first number: ")
//while(scanf("%f",&num1)==0)
//{
// printf("Invalid input. Please enter a number.");
// scanf("%f",&num1);
//}
//printf("Enter second number: ")
//while(scanf("%f",&num2)==0)
//{
// printf("Invalid input. Please enter a number.");
// scanf("%f",&num2);
//}
//answer = num1 + num2;
//printf("%f + %f = %f\n",num1,num2,answer);
//break;
//
//I have also tried to make this work using do-while loops
printf("Enter first number: ");
scanf("%f",&num1);
printf("Enter second number: ");
scanf("%f",&num2);
answer = num1 + num2;
printf("%f + %f = %f\n",num1,num2,answer);
break;
case 's':
printf("Enter first number: ");
scanf("%f",&num1);
printf("Enter second number: ");
scanf("%f",&num2);
answer = num1 - num2;
printf("%f - %f = %f\n",num1,num2,answer);
break;
case 'm':
printf("Enter first number: ");
scanf("%f",&num1);
printf("Enter second number: ");
scanf("%f",&num2);
answer = num1 * num2;
printf("%f * %f = %f\n",num1,num2,answer);
break;
case 'd':
printf("Enter first number: ");
scanf("%f",&num1);
printf("Enter second number: ");
scanf("%f",&num2);
answer = num1 / num2;
printf("%f / %f = %f\n",num1,num2,answer);
break;
default:
printf("That is not a valid operation.\n");
break;
}
}
}
return 0;
}
Again, thanks for any help!
Ya'll would be a life saver!
Cheers!
-Will S.
EDIT: I got my code to work! Here is the final code...
#include <stdio.h>
#include <ctype.h>
int main(void)
{
char ch;
float num1,num2,answer;
printf("Enter the operation of your choice:\n");
printf("a. add s. subtract\n");
printf("m. multiply q. divide\n");
printf("q. quit\n");
while ((ch = getchar())!='q')
{
ch=tolower(ch);
//Ignore whitespace
if (ch=='\n')
continue;
else
{
switch(ch)
{
//Addition part
case 'a':
//First number
printf("Enter first number: ");
//Check to see if input is a number
while (scanf("%f",&num1)==0)
{
printf("Invalid input. Please enter a number, such as 2.5, -1.78E8, or 3: ");
scanf("%*s");
}
//Second number
printf("Enter second number: ");
while (scanf("%f",&num2)==0)
{
printf("Invalid input. Please enter a number, such as 2.5, -1.78E8, or 3: ");
scanf("%*s");
}
//Do math for respective operation
answer = num1 + num2;
//Print out result
printf("%.3f + %.3f = %.3f\n", num1,num2,answer);
break;
//Subtraction part
case 's':
printf("Enter first number: ");
while (scanf("%f",&num1)==0)
{
printf("Invalid input. Please enter a number, such as 2.5, -1.78E8, or 3: ");
scanf("%*s");
}
printf("Enter second number: ");
while (scanf("%f",&num2)==0)
{
printf("Invalid input. Please enter a number, such as 2.5, -1.78E8, or 3: ");
scanf("%*s");
}
answer = num1 - num2;
printf("%.3f - %.3f = %.3f\n", num1,num2,answer);
break;
//Multiplication part
case 'm':
printf("Enter first number: ");
while (scanf("%f",&num1)==0)
{
printf("Invalid input. Please enter a number, such as 2.5, -1.78E8, or 3: ");
scanf("%*s");
}
printf("Enter second number: ");
while (scanf("%f",&num2)==0)
{
printf("Invalid input. Please enter a number, such as 2.5, -1.78E8, or 3: ");
scanf("%*s");
}
answer = num1 * num2;
printf("%.3f * %.3f = %.3f\n", num1,num2,answer);
break;
//Division part
case 'd':
printf("Enter first number: ");
while (scanf("%f",&num1)==0)
{
printf("Invalid input. Please enter a number, such as 2.5, -1.78E8, or 3: ");
scanf("%*s");
}
printf("Enter second number: ");
while (scanf("%f",&num2)==0)
{
printf("Invalid input. Please enter a number, such as 2.5, -1.78E8, or 3: ");
scanf("%*s");
}
//Check for if number is a zero
while (num2==0)
{
printf("Please enter a non-zero number, such as 2.5, -1.78E8, or 3: ");
while (scanf("%f",&num2)==0)
{
printf("Invalid input. Please enter a number, such as 2.5, -1.78E8, or 3: ");
scanf("%*s");
}
}
answer = num1 / num2;
printf("%.3f / %.3f = %.3f\n", num1,num2,answer);
break;
//For if a non-valid operation is entered
default:
printf("That is not a valid operation.\n");
break;
}
}
printf("Enter the operation of your choice:\n");
printf("a. add s. subtract\n");
printf("m. multiply q. divide\n");
printf("q. quit\n");
}
printf("Bye.\n");
return 0;
}
Looking back at it, I probably could do without the if/else statement.
There are multiple problems with your code. First of all in this loop
You are taking input two times on failure
while(scanf("%f",&num1)==0) //Taking Input Here Once
{
printf("Invalid input. Please enter a number.");
scanf("%f",&num1); //Again Taking input.
}
Instead what you wanted was to check the return value of the scanf() and if it was 0 you would execute the loop again, so this would be the way to do that:
int l = 0;
while(l==0){ //Checking l, if it is zero or not, if zero running loop again.
printf("Invalid input. Please enter a number.");
l = scanf("%f",&num1); //Storing Return Value of scanf in l
}
When the program will encounter any line with scanf("%f" , &num1) or scanf("%f" , &num2), it will skip all the white spaces and wait for next input. In the case where the input does not match the format specification, then the input isn't consumed and remains in the input buffer.
int l = 0;
while(l==0){ //Checking l
printf("Invalid input. Please enter a number.");
l = scanf("%f",&num1); //scanf will look at the buffer if the input
//does not match, it will not be consumed
//and will remain in buffer.
}
In other words, the character that doesn't match is never read. So when you type e.g. an a character, your code will loop indefinitely as scanf continues to fail on the same character.
When the program executes its last scanf("%f",&num2) call then because of the enter there is a newline \n character present in buffer and so due to ch = getchar(), new line \n gets stored in ch and the following if condition satisfies and the loop execute again.
if(ch =='\n')
continue;
while(scanf("%f",&num1)==0)
{
printf("Invalid input. Please enter a number.");
scanf("%f",&num1);
}
This loops scans two numbers per iteration. This is not what you want. Lose the second scanf.
You should also check for EOF and errors.
int result;
while((result = scanf("%f",&num1))==0)
{
printf("Invalid input. Please enter a number.");
}
if (result == EOF) .... report an error and exit ...

struct outputs are being overwritten by last user input

Im a beginner to C and I'm having trouble with structs.
after I've asked user for all attributes, id like to print all the values of the struct. The problem is that after I've got input all the attributes to a struct and it loops back again to ask for attributes a second time, the first struct input gets replaced by the second struct input.
I'm pretty sure that I'm allocating the same memory space over and over and thus causing the problem but I'm stuck on how to fix it. Id appreciate any advice on what i can do. thanks!
case 2:
printf ("Please input a SKU number:");
scanf ("%d", &item[MAX_ITEMS].sku_);
printf ("Quantity:");
scanf ("%d", &item[MAX_ITEMS].quantity_);
printf ("Price:");
scanf ("%f", &item[MAX_ITEMS].price_);
printf ("The item is successfully added to the inventory");
break;
to print out the sku, quantity and price
switch (menuSelection) {
case 1:
printf ("Inventory\n");
printf ("=========================================\n");
printf ("Sku Price Quantity\n");
for (i =0 ; i<=MAX_ITEMS; i++){
printf ("%d %.2f %d\n", item[i].sku_, item[i].price_, item[i].quantity_);
}
printf ("=========================================\n");
break;
here is my whole code:
#include <stdio.h>
#define MAX_ITEMS 10
struct Item{
int sku_;
float price_;
int quantity_;
}item[MAX_ITEMS];
int main (void) {
int size=0;
int menuSelection;
int i=0;
printf ("Welcome to the Shop\n");
printf ("===================");
do {
printf ("\nPlease Select from the following options:\n");
printf ("1) Display the inventory.\n");
printf ("2) Add to shop.\n");
printf ("0) Exit.\n");
printf ("select:");
scanf ("%d", &menuSelection);
if (menuSelection <0 && menuSelection >2){
printf ("Invalid input, try again: Please select from the following options:");
}
else {
switch (menuSelection) {
case 1:
printf ("Inventory\n");
printf ("=========================================\n");
printf ("Sku Price Quantity\n");
for (i =0 ; i<=MAX_ITEMS; i++){
printf ("%d %.2f %d\n", item[i].sku_, item[i].price_, item[i].quantity_);
}
printf ("=========================================\n");
break;
case 2:
printf ("Please input a SKU number:");
scanf ("%d", &item[size].sku_);
printf ("Quantity:");
scanf ("%d", &item[size].quantity_);
printf ("Price:");
scanf ("%f", &item[size].price_);
printf ("The item is successfully added to the inventory");
break;
case 3:
break;
}
}
} while (menuSelection != 0);
return 0;
}
You create an array of Item objects with the length of MAX_ITEMS, currently being 10. That is, your objects have the indices of 0 to 9. Yet when asking the user for input, you always store the data at item[MAX_ITEMS] which is out of bounds of your array.
As a side note, when printing your array, you always print it whole, meaning also uninitialised items.
You have to store how many items are already "added to the shop" and use this number to determine the next array index where user input has to be stored. When printing you only have to iterate over the items already stored. Don't forget bounds checking, e.g. don't allow new user input when your shop is full.
The problem is that you always save the new values in the same place:
item[MAX_ITEMS].sku_
Instead, you should have a counter that show how many items are stored and save the new values in the place that is equal to the counter:
item[counter].sku_
and after every insertion you should increase the counter:
counter++;
So, your code should look like this:
int counter=0;
...
case 2:
printf ("Please input a SKU number:");
scanf ("%d", &item[counter].sku_);
printf ("Quantity:");
scanf ("%d", &item[counter].quantity_);
printf ("Price:");
scanf ("%f", &item[counter].price_);
printf ("The item is successfully added to the inventory");
counter++;
break;
I hope I was helpful
The item you defined is a array with size of MAX_ITEMS, so the problem of you is not about struct but array.
In most of computer programming language, indexing an array should use a offset start on zero. That is, MAX_ITEMS of item[MAX_ITEMS] is out of range for the array, you got a bug and do not find it. When you adding a item to your shop, you should code like this:
case 2:
if (last < MAX_ITEMS - 1)
{
printf ("Please input a SKU number:");
scanf ("%d", &item[last].sku_);
// ...
last ++; // on success
}
else
{
print("oops, shop is full.");
}

How to make getchar() read a negative number?

I am writing a program that can calculate the areas of a square, cube, and circle. The program needs to present an error message and allow the user to enter a new choice if they enter something not included in the menu. My problem is that if they type anything includes my menu options then the program still executes. (i.e. -1, 23, 344) I was wondering how to get it to ignore anything after the first character or to read the whole string. Or if there is something better than getchar(). I'm open to any solutions! Thank you!
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int choice;
int lengthsq;
int areasq;
int lengthcube;
int areacube;
int radius;
double circlearea;
printf("Area Calculation\n");
printf("(1) Square\n");
printf("(2) Cube\n");
printf("(3) Circle\n");
fputs("Please make a selction: ", stdout);
while((choice = getchar()) != '\n')
switch (choice) {
case '1':
printf("\nPlease enter the length: ");
scanf("%d", &lengthsq);
while(lengthsq <= 0){
printf("Error! Please enter a positive number: ");
scanf("%d", &lengthsq);
}
areasq = lengthsq * lengthsq;
printf("The area of the square is %d.", areasq);
return 0;
case '2':
printf("\nPlease enter the length: ");
scanf("%d", &lengthcube);
while (lengthcube <= 0) {
printf("Error! Please enter a positive number: ");
scanf("%d", &lengthcube);
}
areacube = 6 * lengthcube * lengthcube;
printf("The surface area of the cube is %d.\n", areacube);
return 0;
case '3':
printf("\nPlease enter the radius: ");
scanf("%d", &radius);
while(radius <= 0){
printf("Error! Pleae enter a postive number: ");
scanf("%d", &radius);
}
circlearea = 3.14159 * radius * radius;
printf("The area of the circle is %.2f.\n", circlearea);
return 0;
case '\n':
case '\t':
case ' ':
break;
default:
printf("\nInvalid choice entered.\n");
fputs("Enter a new choice: ", stdout);
break;
}
}
You could add another switch case for the dash, which would toggle some kind of negative flag and then read a number as you're already doing. If you do not like introducing such a flag, then the best option would be using fgets, which returns the entire input line. But that has the downside that you need to parse the input. I.e. do some string manipulation, which may be slightly more complex than a simple flag parameter.
On the other hand, from the code you attached, I deduct that the only valid input consists of mere numbers (integers). You could just read an integer then with scanf.

How to loop until user input N in C

I'm a beginner in C program, and I'm trying to make a restaurant order menu.
I start with user input "Y" to start order.
Then I want the program to keep taking orders until user input "N" to stop.
When input "N", the total sales will printed.
But I cannot do the looping, would you mind to help me? Thank you. :)
#include <stdio.h>
#include <stdlib.h>
int main()
{
int code;
float totalPrice=0, totalSales = 0 ;
char choice, choice1;
printf("Welcome to Deli Sandwich! Enter Y to start your order!\n");
scanf("%c", &choice);
while(choice=='Y'|| choice=='y')
{
printf("\n____________________________SANDWICH FILLING______________________________\n");
printf("\n\t\t Menu \t\t Code \t\t Price\n");
printf("\n\t\t Egg \t\t 1 \t\t RM 1.00\n");
printf("\n\t\t Tuna \t\t 2 \t\t RM 2.00\n");
printf("\n\t\t Seafood \t 3 \t\t RM 3.00\n");
printf("\n\t\t Chicken Ham \t 4 \t\t RM 2.50\n");
printf("\nSandwich Filling code: ");
scanf("%d", &code);
switch(code)
{
case 1:
printf("Egg is picked.\n");
totalPrice+= 1;
break;
case 2:
printf("Tuna is picked.\n");
totalPrice+= 2;
break;
case 3:
printf("Seafood is picked.\n");
totalPrice+= 3;
break;
case 4:
printf("Chicken Ham is picked.\n");
totalPrice+= 2.50;
break;
default :
printf("invalid code.");
}
printf("\n_____________________________SANDWICH TYPE________________________________\n");
printf("\n\t\t Menu \t\t Code \t\t Price\n");
printf("\n\t\t Half \t\t 1 \t\t RM 3.00\n");
printf("\n\t\t Whole \t\t 2 \t\t RM 5.00\n");
printf("\nSandwich Type code: ");
scanf("%d", &code);
switch(code)
{
case 1:
printf("Half is picked.\n");
totalPrice+= 3;
break;
case 2:
printf("Whole is picked.\n");
totalPrice+= 5;
break;
default :
printf("invalid code.");
}
printf("\nThe total price is RM%.2f.\n", totalPrice);
printf("Thank You. Please come again!\n");
totalSales+= totalPrice;
printf("\nWelcome to Deli Sandwich! Enter Y to start your order!\n");
scanf("%c", &choice);
}
printf("\nThe total sales is RM%.2f.\n", totalSales);
return 0;
}
Thank you again :)
Change
scanf("%c", &choice);
to
scanf(" %c", &choice); // note the space before %c
This is done to discard all white-space characters like \n and spaces from the stdin.
When you enter data for a scanf,you enter some data and press the enter key. scanf consumes the data entered and leaves the \n(enter key) in the input buffer(stdin). When scanf with a %c is called the next time, it will take the \n as input(left over by the previous scanf) and will not wait for further input.
In your code,
scanf("%c", &choice);
before the while loop consumes the character you entered and leaves the \n in the stdin. As for why
scanf("%d", &code);
waits for input is that the %d format specifier skips white-space characters while %c does not.
scanf(" %c", &choice);
Ignore the newline character at the end of the input by placing a space before %c
simple add the space before %c
The ENTER key press after providing the input is stored into the input buffer stdin and considered a valid input for %c format specifier for the recurring scanf()s. To avoid scanning the stored \n, you need to change your code like
scanf(" %c", &choice);
^
|
This leading space indicates to ignore any leading whitespace or whitespace-like characters (including \n) and scan the first non-whitespace character. [In your case y/ Y/ n...]

I cannot seem to loop again after selecting default in switch case in C

hello guys I coded something like kfc menu,and I got it to work(finally),but when I input something other than numbers for "menu",eg:the letter "A", I just can't get it to loop again to normal,instead it finishes the program
#include <stdio.h>
#include <stdlib.h>
int main()
{
char counter='y';
float totalprice=0;
while (counter=='Y' || counter=='y')
{
int menu;
float price=0;
printf("\nplease select from menu:");
scanf (" %i", &menu);
switch(menu)
{
case 1: {
printf("\none hotbox1 =RM10.50");
totalprice=totalprice+10.50;
break;
}
case 2: {
printf ("\none hotbox2=RM10.60");
totalprice=totalprice+10.60;
break;
}
case 3:{
printf ("\none hotbox3=RM10.70");
totalprice=totalprice+10.70;
break;
}
default : {
printf ("\nplease enter proper number please:");
scanf("%2f", &menu);
break;
}
}
printf("\n\nadd order?(Y/N):");
scanf (" %c", &counter);
}
printf("\n\nThe total price is: %f", totalprice);
return 0;
}
You should use fgets() (reference here) first and then sscanf() (reference here), checking it's return value to see if it's a number.
char inputBuffer[MAX_BUFFER];
do
{
fgets(inputBuffer, MAX_BUFFER, stdin);
}
while(sscanf(inputBuffer, "%d", &menu) != 1)
You scanf with %f in the default case, I am fairly certain that is for floats. Use %d.
Remove scanf("%2f", &menu);
Switch in C does not support char in switch-case. Before you start switch-case validate the user input. If it is a number go into switch case otherwise display a user message to enter only numeric value
I recommend that you debug this by printing out the value of "counter" at various points in the loop (i.e. after you read it in, at the bottom of the loop, etc.). This will give you visibility into what your code is doing.
You can try something like this
#include <stdio.h>
int main()
{
char counter;
float totalprice=0;
int menu=0;
do
{
printf("\n1. one hotbox1=RM10.50");
printf("\n2. one hotbox2=RM10.60");
printf("\n3. one hotbox3=RM10.70");
printf("\nplease select from menu:");
scanf ("%d", &menu);
switch(menu)
{
case 1:
printf("\none hotbox1 =RM10.50");
totalprice=totalprice+10.50;
break;
case 2:
printf ("\none hotbox2=RM10.60");
totalprice=totalprice+10.60;
break;
case 3:
printf ("\none hotbox3=RM10.70");
totalprice=totalprice+10.70;
break;
default :
printf ("\nplease enter proper number please:");
scanf("%d", &menu);
}
printf("\n\nadd more order?(Y/N):");
fflush(stdin); //to empty the input stream.
scanf("%c",&counter);
}while(tolower(counter) != 'n'); //tolower returns the lowercase character.
printf("\n\nThe total price is: %.2f", totalprice);
return 0;
}
When scanf("%i", &menu) tries to read an integer from the input, it finds A, which it cannot interpret as a number, so it does not read it(*). Then the next scanf continues reading the input from when the other left off and happily reads the letter 'A'. Since you loop as long as the read letter is either 'y' or 'Y' (which A is neither), it exits the loop.
(*) read up on the documentation of scanf to see how to tell if it encountered an error.
Note: scanf("%i", &menu) should be scanf("%d", &menu) as%d` is the formatting symbol for integers.
One solution would be to change the loop condition to:
while (counter!='N' && counter!='n')
{
...
}
This way you end the loop only if an explicit 'N' or 'n' is inputted.
Note: it won't help if you accidentally type 'n' for the menu item, so see the comment about the error handling above.

Resources