determining the proper loop to use - c

I am trying to teach myself C. For fun and for my own development, I have created a code that prompts the user for a letter grade, then outputs the range of that letter grade. Here is what I have so far:
//Ted C. Lim
#include "stdio.h"
int main()
{
char grade;
printf("Enter a single character grade: ");
scanf("%c", &grade);
printf("You entered %c as the grade. ", grade);
switch(grade)
{
case 'A':
printf("The grade range for A and A- is 100%% - 90%%.");
break;
case 'B':
printf("The grade range for B and B- is 80%% - 89%%.");
break;
case 'C':
printf("The grade range for C and C- is 70%% - 79%%.");
break;
case 'D':
printf("The grade range for D and D- is 60%% - 69%%.");
case 'F':
printf("The grade range for F is 0%% - 59%%.");
default:
printf("That grade does not exist.");
break;
}
}
If you run the program, you will see that it asks the user only once, returns the proper output, then stops. What I would like to do is repeat the prompt indefinitely until the user inputs something like 'Q' to quit. I know I should use some sort of loop here, but I'm not quite sure how to apply it.

There a couple different options you could choose here, both the while and the do while loop would work. Personally, I would say that a do while loop would be better fit for this case, mostly because you know for sure that you want the program to prompt the user at least once. In order to use it you would need to place the do before the printf statements and then run while some scanf input at the end is != "Q"

You can use a while loop, along with another character case to exit out of the loop.
char grade;
while (1)
{
printf("Enter a single character grade (or 'X' to exit): ");
scanf(" %c", &grade);
printf("You entered %c as the grade. ", grade);
if (grade == 'X') // Or another letter, make it clear what you're using
{
break;
}
// Output code here...
}
I would also recommend you check for both lowercase and uppercase letters. In the switch statement:
case 'A':
case 'a':
printf("The grade range for A and A- is 100%% - 90%%.");
break;
In the if statement:
if (grade == 'X' || grade == 'x')
{
break;
}

To repeat an action indefinitely, you could wrap it inside a while loop with a condition that is always true (e.g., while (1) { ... }) as follows:
#include <stdio.h>
#include <ctype.h>
int main()
{
char grade;
while (1)
{
printf("Enter a single character grade (or Q to quit):\n");
scanf(" %c", &grade);
grade = toupper(grade);
if (grade == 'Q') break;
printf("You entered %c as the grade.\n", grade);
switch(grade)
{
case 'A':
printf("The grade range for A and A- is 100%% - 90%%.\n");
break;
case 'B':
printf("The grade range for B and B- is 80%% - 89%%.\n");
break;
case 'C':
printf("The grade range for C and C- is 70%% - 79%%.\n");
break;
case 'D':
printf("The grade range for D and D- is 60%% - 69%%.\n");
break;
case 'F':
printf("The grade range for F is 0%% - 59%%.\n");
break;
default:
printf("That grade does not exist.\n");
break;
}
}
return 0;
}
You'll notice I've made a few other modifications, which I'll run through here:
include "stdio.h" should really be #include <stdio.h>. The angle brackets tell the compiler to look in the standard directory for system header files.
I also added #include <ctype.h> because I'm using the toupper() function to convert the input character to upper case. This makes your code easier to use, because it will now accept both upper and lower case letters.
The scanf() format string includes a space before %c. This will skip over any white space characters including newline characters. Without it, the program would treat these characters as actual inputs and tell you that the \n grade does not exist.
The break statement can be used to exit the loop when the user enters Q. There were also a couple of breaks missing from your switch block.
The main() function is declared as int main() { ... }, so it should return an integer value. If no errors have occurred, this value should be zero.

Encase your switch case inside of a while loop that is true and it will run indefinitely. You can also use scanf to check for a specific key to be entered to stop it too.

Related

Basic C - Switch cases duplication

I am working on a project, where you answer a char, and if it is not one of the 4 answers, it tells you to try again. If it is not the correct one of the 4, it stops running. Here is a snippit.
#include <stdio.h>
#include <stdbool.h>
bool switchCheck = true;
char answer;
printf("A. English\nB. French\nC. Spanish\nD. German\n");
do{
scanf("%c\n", &answer);
switch (answer){
case 'C':
printf("Very nice ");
break;
case 'B':
case 'A':
case 'D':
printf("Sorry! Incorrect. Code Ends\n");
switchCheck =false;
break;
default:
printf("Try Again\n");
}
}while(switchCheck==true);
For some reason, when I input A, B, or D, it first prints the result for default, and if I do it again immediately afterward, it gives me the right input. Any help?
Thanks!
You are using scanf like
scanf("%c\n", &answer);
Instead use
scanf( " %c", &answer );
See the blank before the conversion specifier %c. It allows to skip white spaces.

Can the argument for Switch statement have an expression to eliminate a variable used for comparison? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
This program simulates a simple menu driven calculator with +, -, *, and / operations
#include <stdio.h>
#include <conio.h>
int main()
{
float a = 0, b = 0;
printf(" Enter two numbers: ");
scanf(" %f %f",&a ,&b);
puts(" Enter choice number of operation: ");
puts(" 1)Addition ");
puts(" 2)Subtraction ");
puts(" 3)Multiplication ");
puts(" 4)Division ");
flushall(); //To clear the trailing '\n'
switch( getchar() - 48 )
{
case 1: printf("The Sum of %.2f and %.2f is : %.2f",a,b,(a+b));
break;
case 2: printf("The Difference of %.2f and %.2f is : %.2f",a,b,(a-b));
break;
case 3: printf("The Product of %.2f and %.2f is : %.2f",a,b,(a*b));
break;
case 4: if ( b != 0 ) printf("The Quotient of %.2f and %.2f is : %.2f",a,b,(a/b));
else puts("Error, divide by zero not possible.");
break;
default: puts("Error, Invalid choice");
}
return 0;
}
Is it better this way? As I have avoided the usage of a variable, and equivalently described why the program crashes when the last input is not a valid choice, I don't think there is any need to add info about what was entered. It adds an extra variable into the picture.
Yes, switch statement can take an expression for the value on which you switch. Your code should work fine, except that getchar() would read the leftover '\n' character from scanf of the operands.
Add another call to getchar() before the switch to read and discard that extra character.
While the code is valid and correct, I'd do the following to make it more readable:
switch(getchar()) {
case '1': // ...
case '2': // ...
case '3': // ...
case '4': // ...
}
Or
switch(getchar() - '0') {
case 1: // ...
case 2: // ...
}
This is to avoid using the magic number 48, which may not be understood easily by readers.
Furthermore, you can discard input until the next \n using a simple while loop:
while(getchar() != '\n') ;
In addition to the \n, this will also read and discard anything before the newline.
switch ( expression )
So you have a valid expression and you can have a expression like you have if you really have a need for something like this.
Else
char ch = getchar(); /* or scanf(" %c",&ch); (Better)*/
int a = ch - '0';
switch(a)
{
}
For your answer : Yes the switch can accept an expression in its arguments but it should returns only one of these types char int short long int long long int it can be also signed or unsigned !
There is no need to make a cast for the expression getchar() - 48 because getchar() returns int and 48 is an int so th result would be an int
now after compiling you have to add 3 number one for the variable a and the second for the variable b and the third for the switch statement... for instance
$./executable_file
Enter two numbers: 1 2 3
Switch formatting
This is a suggested formatting of your switch statement. I disagree with the idea of using getchar() in the switch statement (though it is technically legal, it is simply a bad idea in practice), so I've replaced that with c:
int c;
/* c is set by some input operation.
** It might be char c; if you read its value with scanf(), but it must be int if you use getchar()
*/
switch (c)
{
case 1:
printf("The Sum of %.2f and %.2f is : %.2f", a, b, (a+b));
break;
case 2:
printf("The Difference of %.2f and %.2f is : %.2f", a, b, (a-b));
break;
case 3:
printf("The Product of %.2f and %.2f is : %.2f", a, b, (a*b));
break;
case 4:
if (b != 0)
printf("The Quotient of %.2f and %.2f is : %.2f",a, b, (a/b));
else
fputs("Error, divide by zero not possible.\n", stderr);
break;
default:
fprintf(stderr, "Error, Invalid choice %c\n", c);
break;
}
Note the use of break; after the default: label too; it protects you against future additions to the code and is completely uniform. (The default: label does not have to be last, though that is the conventional place for it to go.) Commas get a space after them; so do if, for, while, switch, but function calls do not get a space between the name and the open parenthesis. You don't normally need a space after an open parenthesis or before a close parenthesis. Errors are reported to standard error.
Personally, I like the actions of the switch to be indented just one level, not two levels, so I'd use:
switch (c)
{
case 1:
printf("The Sum of %.2f and %.2f is : %.2f", a, b, (a+b));
break;
case 2:
printf("The Difference of %.2f and %.2f is : %.2f", a, b, (a-b));
break;
case 3:
printf("The Product of %.2f and %.2f is : %.2f", a, b, (a*b));
break;
case 4:
if (b != 0)
printf("The Quotient of %.2f and %.2f is : %.2f",a, b, (a/b));
else
fputs("Error, divide by zero not possible.\n", stderr);
break;
default:
fprintf(stderr, "Error, Invalid choice %c\n", c);
break;
}
Many people disagree, so you're certainly not under an obligation to do that.

switch statement creating infinite loop

I am writing a piece of code and in one part of my code I am using a switch statement in C language. if I press n it exits correctly if I press y it will infinite loop the default statement until I press control c. what am I doing wrong here. been changing the while statement but can't find the right one.
int main()
{
char ans;
printf("DO you want to continue?");
scanf("%c", &ans);
do
{
switch(ans)
{
case 'y':
some stuff...
printf("DO you want to continue?");
scanf("%c", &ans);
break;
case'n':
printf("BYE");
break;
default:
printf("error, you must enter y or n");
continue;
}
}
while (ans!='n');
return 0;
}
When you press enter, the linefeed character \n is added to the input stream. Your code does not anticipate this, because switch(ans) only handles y, n or “everything else” (which includes the linefeed character).
To fix this, allow scanf to ignore any preceding whitespace by changing your format string to " %c" instead, e.g.
scanf(" %c", &ans);
// ^ space character inserted here
I think it would make more sense to move the scanf call to inside the loop, like this:
int main()
{
char ans;
do
{
printf("DO you want to continue?");
if (scanf(" %c", &ans) != 1)
break;
switch(ans)
{
case 'y':
// some stuff...
break;
case 'n':
printf("BYE");
break;
default:
printf("error, you must enter y or n");
continue;
}
}
while (ans!='n');
}
Don't forget to always check the result of scanf(). It will return the number of items successfully scanned (in your case, you want it to return 1). If it returns 0 or a negative number, then another problem has occurred.

Last array number keeps going wrong after switch statment

For example if i enter: "123456-7". The output at the first print statement would be: "123456-7" and at the 2nd print statement it would be "7". Which is correct.
But at any point after the break if I print the array again the print statement would go wrong in the last digit. It would look like: "123456-1" and the second would look like "1".
#include <stdio.h>
int main()
{
int lotoNumbers[6];
int ticketNumbers[6];
char option;
while(option != 'C')
{
printf("Your option:");
scanf(" %c", &option);
switch(option)
{
case 'W': printf("Please enter todays winning ticket number:");
scanf("%1d%1d%1d%1d%1d%1d-%1d", &lotoNumbers[0], &lotoNumbers[1], &lotoNumbers[2], &lotoNumbers[3], &lotoNumbers[4], &lotoNumbers[5], &lotoNumbers[6]);
printf("Your loto ticket number is: %d%d%d%d%d%d-%d\n", lotoNumbers[0], lotoNumbers[1], lotoNumbers[2], lotoNumbers[3], lotoNumbers[4], lotoNumbers[5], lotoNumbers[6]);
printf("----The following numbers matched! %d\n", lotoNumbers[6]);
break;
case 'T': printf("Please enter your ticket number:");
scanf("%1d%1d%1d%1d%1d%1d-%1d", &ticketNumbers[0],&ticketNumbers[1],&ticketNumbers[2],&ticketNumbers[3],&ticketNumbers[4],&ticketNumbers[5],&ticketNumbers[6]);
printf("Your loto ticket number is: %d%d%d%d%d%d-%d\n", ticketNumbers[0], ticketNumbers[1], ticketNumbers[2], ticketNumbers[3], ticketNumbers[4], ticketNumbers[5], ticketNumbers[6]);
break;
case 'C': printf("Computing....\n");
break;
case 'Q': printf("The program will now quit. Thank you for playing LOTO 649.\n");
return (0);
break;
default: printf("You entered an invalid option. The program will now terminate.\n");
return (0);
}
}
printf("The numbers are:%d%d%d%d%d%d-%d\n", lotoNumbers[0], lotoNumbers[1], lotoNumbers[2], lotoNumbers[3], lotoNumbers[4], lotoNumbers[5], lotoNumbers[6]);
printf("The number is: %d\n", lotoNumbers[6]);
return 0;
}
You didn't allocate enough space for your arrays. The number used to allocate space for an array is the number of entries in the array, not the last index number. Index 6 is the 7th item and is past the end of the array. The value of lotoNumbers[6] is undefined and can change randomly, because the program is using that memory for something else.
int lotoNumbers[6];
int ticketNumbers[6];
That 6 should be 7.

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