C: can't figure out what is causing an infinite loop - c

I'm a beginner, and as an exercise I have to code a very simple calculator that modifies the stack by the number and the operator the user inputs.
This is the code:
#include <stdio.h>
int main (void)
{
long double x, stack = 0;
char op;
printf("Input an operator and a number:\n");
while ( op != 'q' )
{
scanf("%Lf %c", &x, &op);
switch (op)
{
case '+':
stack += x;
printf("= %Lg", stack);
printf("\n");
break;
case '-':
stack -= x;
printf("= %Lg", stack);
printf("\n");
break;
case '*':
stack *= x;
printf("= %Lg", stack);
printf("\n");
break;
case '/':
if (x == 0)
{
printf("Can't divide by 0.");
printf("\n");
break;
}
stack /= x;
printf("= %Lg", stack);
printf("\n");
break;
case 's':
stack = x;
printf("stack set to %Lg", x);
printf("\n");
break;
case 'q':
printf("Bye!\n");
break;
default:
printf("Unknown operator.\n");
break;
}
}
printf("Bye!\n");
return 0;
}
Now the problem is that whenever x is not an number, the program keeps looping. Why?
And how could I prevent the user from inputing anything but a number for x? If x was a char I'd use isdigit(), but that's not the case.
(By the way, I want x to be a long double so I can input numbers with decimals).

scanf() will convert as many values from the string as it can. If one cannot be converted, it stops processing the string. Either way, the function returns a value indicating how many values were converted.
If the first value (x) is not a number and cannot be converted, it stops. And so the second value (op) does not change. That causes your loop to continue.
Check the value returned by scanf() to confirm this behavior yourself.
Also, "I want x to be a long double so I can input numbers with decimals" - Values of type float and double also support numbers with decimals.
Finally, as others have point out, you should initialize op at the start of your code before testing if it equals "q". This will ensure the value is what you expect it to be at that time.

Related

I keep getting a segmentation fault in my C code

First off, I am relatively new to C programming, and wanted to write a program that would be able to accept user input and then pass that on to a switch/case and return output based on the initial choice. I was able to do this while using the int data type, but I would like some help doing the same while taking input as a char.
#include <stdio.h>
double x = 1;
double y = 3;
char inputLet[1];
double chooseEquation(char notLet){
char notNotLet = notLet;
printf("notLet here is: %c \n", notLet);
switch(notLet){
case 'A':
x += y;
printf("Case1 reached! \n");
break;
case '2':
x += -y;
break;
case '3':
x -= y;
break;
case '4':
x -= -y;
break;
case '5':
x *= y;
break;
case '6':
x *= -y;
break;
default :
printf("defaulting! btw: %c \n", notNotLet);
x = 0;
}
printf("x has been set? Here: %.2f\n", x);
return x;
}
int main(){
printf("Welcome, please pick a letter from A to F (uppercase for now) in order to choose an equation: \n");
scanf(" %c", &inputLet);
printf("The letter you chose is: %s \n", inputLet);
double outputLet = chooseEquation(inputLet);
printf("Your equation evaluated to: %.2f \n", outputLet);
return 0;
}
Somehow, no matter the input, the character that the switch looks at becomes Q
However, if I replace this line:
char inputLet[1];
with this line:
char inputLet;
The program segmentation faults.
Any help would be much appreciated.
printf("The letter you chose is: %s \n", inputLet);
When you use char inputLet then use %c. This is causing the error.
And also if it is a single character then just use char inputLet not a character array.
After changing it, I tested it locally and got this output for 'A'
Welcome, please pick a letter from A to F (uppercase for now) in order to choose an equation:
A
HelloThe letter you chose is: A
notLet here is: A
Case1 reached!
x has been set? Here: 4.00
Your equation evaluated to: 4.00

Exercise #5 Chapter 6 of Programming in C

Write a program that acts as a simple "printing" calculator. The program should allow the user to type in expressions of the form: number operator. The following operators should be recognized by the program: +, -, *, /, S. E
The S operator tells the program to set the "accumulator" to the typed-in number.
The E operator tells the program that execution is to end.The arithmetic operations are performed on the contents of the accumulator with the number that was keyed in acting as the second operand.
The following is a "sample run" showing how the program should operate:
Begin Calculations
10 S Set Accumulator to 10
= 10.000000 Contents of Accumulator
2 / Divide by 2
= 5.000000 Contents of Accumulator
55 - Subtract 55
-50.000000
100.25 S Set Accumulator to 100.25
= 100.250000
4 * Multiply by 4
= 401.000000
0 E End of program
= 401.000000
End of Calculations.
Here's my code
#include <stdio.h>
int main(void)
{
char op;
float acc = 0, num;
printf("Begin Calculations\n");
while (op != 'E') {
scanf("%f %c", &num, &op);
switch (op) {
case '+':
acc += num;
printf("= %f\n", acc);
break;
case '-':
acc -= num;
printf("= %f\n", acc);
break;
case '*':
acc *= num;
printf("= %f\n", acc);
break;
case '/':
if (num == 0) {
printf("Division by zero\n");
}
else {
acc /= num;
printf("= %f\n", acc);
}
break;
case 'S':
acc = num;
printf("= %f\n", acc);
break;
case 'E':
printf("= %f\n", acc);
break;
default:
printf("Unknown operator\n");
break;
}
}
printf("End of Calculations");
}
My code work perfectly with the question input. However, when I input the following (and the output) (same input as question but without space between "number" and "operator"):
Begin Calculations
10S
= 10.000000
2/
= 5.000000
55-
-50.000000
100.25S
= 100.250000
4*
= 401.000000
0E
The program stuck when I input 0E. I have tried to change scanf("%f %c", &num, &op); to scanf("%f%c", &num, &op); but it didn't seem to solve my problem. Could you point out the problem in my code? Please give me a detail explaination because I'm relative new to C. Thank you in advance for any help you can provide.
You are reading a float value. So if scanf sees 0E, it awaits more digits as it thinks you are inputting an exponential as e.g. 0E5 (=0*10^5). That's why your program gets stuck at this point. I would suggest to use a different character to end to avoid this ambiguity.
If, on the other hand, scanf sees 0S, it will output 0.0 as float value and 'S' as character, as 'S' is never a valid part of a float value.

calculator output in c

I made a simple calculator program using switch case, but the output is different than I expected.
int main(){
double a, b;
double sum = 0;
char o; //operator
printf("Enter operator\n");
scanf("%c", &o);
printf("Enter first operand\n");
scanf("%f", &a);
printf("Enter second operand\n");
scanf("%f", &b);
switch (o)
{
case '+':
sum = a + b;
break;
case '-':
sum = a - b;
break;
case '*':
sum = a * b;
break;
case '/':
sum = a / b;
break;
if (b == 0){ printf("Error"); }
break;
}
printf("The result is\n%10.10lf\n", sum);
getchar();
getchar();
}
The result of 'sum' is some huge astronomical numbers. Can someone tell why?
Try %lf instead of %f because that way you will have a and b as the type double rather than float.
a and b are both of type double. The correct format specifier for double in scanf is %lf, not %f (which is for float).
scanf("%lf", &a);
Note that in printf, %f is used or for double (the same for float because it's promoted to double). Since C99, %lf in printf is the same as %f.
you are trying to convert double to float which is not implicitly possible inside scanf or printf function. What scanf was doing, It was purging/reformatting the whole (double)input into an empty float value. Here is working one :
#include<stdio.h>
int main(){
double a, b;
double sum = 0;
char o; //operator
printf("Enter operator\n");
scanf("%c", &o);
printf("Enter first operand\n");
scanf("%lf", &a);
printf("Enter second operand\n");
scanf("%lf", &b);
switch (o)
{
case '+':
sum = a + b;
break;
case '-':
sum = a - b;
break;
case '*':
sum = a * b;
break;
case '/':
sum = a / b;
break;
if (b == 0){ printf("Error"); }
break;
}
printf("The result is\n %f\n", sum);
}
As everyone has pointed out, you need scanf ("%lf", &a); and same for b.
Now in your switch statement you wanted to prevent division by zero :
case '/':
sum = a / b;
break;
if (b == 0){ printf("Error"); }
break;
But what happens there is that you break; before getting to the condition. Suppose we removed that first break; the division by zero is still performed before you print the error message anyway.
One way to prevent division by zero would be :
case '/':
if (b)
sum = a / b;
else
printf("Error");
break;
where we check that b != 0 before we make the division and then we either divide or print the error message.

Switch statement letter to integer

Assume that grades from A to F correspond to numbers from 1 to 6. Write a program that has three letter grades as inputs and prints the average numerical grade. My code looks like this : PS: I want this to print out the average of three letter inputs. (I take into account this code could be completely wrong, thus the final code should contain the "switch" and the calculation of the three corresponding values in numbers/interger. please help).
int main(){
char x,y,z;
int num;
float avg;
printf("\n Give three grades:\n");
scanf("%d %d %d", &x, &y, &z);
switch(x,y,z){
case 'a': return 1;
break;
case 'b': return 2;
break;
case 'c': return 3;
break;
case 'd': return 4;
break;
case 'e': return 5;
break;
case 'f': return 6;
break;
}
avg = x+y+z /3;
printf("\n The average is: %d \n", avg);
return 0;
}`
You can only switch on one value at a time. Why don't you make it a function:
int grade_value( char grade )
{
switch(grade) {
case 'a':
case 'A':
return 1;
case 'b':
case 'B':
return 2;
// etc...
default:
return 0;
}
}
Then just call it for each of x, y, and z. You really don't need to use a switch at all, but nevermind. eg
int grade_value( char grade )
{
int value = tolower(grade+1) - 'a';
return (value >= 1 && value <= 6) ? value : 0;
}
Also, note that you should use %f to output a float, not %d (which outputs an int).
You've also misunderstood how switch works. In your main, you switched and return from each case. That would exit main and return a value. That means your program would terminate.
You can use return in the function I suggested for you, because it's not your main. It will immediately return the given value from the function, thus you don't need `break'.

How to have a C program respond to a letter and spit out something else?

I can't seem to get this program to compile.
I keep getting the error:
'Ammonia' undeclared 'Carbon_Monoxide' undeclared
and so on. Am I using the right function with switch?
/*This program will report the content of a compressed-gas cylinder based on the first letter of the cylinder's color.*/
#include <stdio.h>
int main (void)
{
int x;
char o, b, y, g;
int pause;
o = Ammonia;
b = Carbon_Monoxide;
y = Hydrogen;
g = Oxygen;
printf(" Enter a character representing the observed color of the cylinder \n" );
scanf("%d", &x);
switch (x)
{
case 'o': printf("The content is Ammonia\n");
case 'b': printf("The content is Carbon Monoxide\n");
case 'y': printf("The content is Hydrogen\n");
case 'g': printf("The content is Oxygen\n");
default: printf("Character out of range \n");
}
printf("After Switch \n");
printf("Enter new character to continue \n");
scanf("%d", &pause);
return 0;
}
It has nothing to do with your switch statement, but you will probably have to puzzle over the meaning of these four lines:
o = Ammonia;
b = Carbon_Monoxide;
y = Hydrogen;
g = Oxygen;
You don't use the variables thus defined anywhere, and the symbols "Ammonia", "Carbon_Monoxide" and so on are not defined - this is the cause of the error you are seeing.
Since this is homework, I don't want to give you the answer straight, but look at what you're doing with those chars (o, b, y, g) and ask yourself if it makes sense.
Also, on the switch statement, I'm pretty sure you need a break; after each case, else it will print each case's statement
try:
#include <stdio.h>
int main (void)
{
char x;
int pause;
printf(" Enter a character representing the observed color of the cylinder \n" );
scanf("%c", &x);
while(x){
switch (x)
{
case 'o': printf("The content is Ammonia\n"); break;
case 'b': printf("The content is Carbon Monoxide\n"); break;
case 'y': printf("The content is Hydrogen\n"); break;
case 'g': printf("The content is Oxygen\n"); break;
default: printf("Character out of range \n");
}
printf("After Switch \n");
printf("Enter new character to continue \n");
scanf(" %c", &x);
if(x == 'q'){
break;
}
}
return 0;
}

Resources