I keep getting a segmentation fault in my C code - c

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

Related

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

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.

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.

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