C calculator program keeps giving error when I input "sine"? - c

Hi I am new to programming and have been working on a calculator for a while now. I am trying to add some trig functions in and I am having trouble with sine. The other functions work (+, -, *, /) but when I put in "sine" it skips to the part of the code where it says it is an incorrect function. Please help out with my code. Thanks!
#include <stdio.h>
#include <math.h>
int main()
{
float firstnum, secondnum, angle, answer, pi;
char function, sine;
pi = atan(1.0)*4;
printf("\nHello and welcome to my calculator!\n");
while(1)
{
printf("\nPlease input the function you would like to use. These include +, -, *, /, sine.\n");
scanf("%s", &function);
switch(function)
{
case '+':
printf("\nNow please input the two variables.\n");
scanf("%f", &firstnum);
scanf("%f", &secondnum);
answer = firstnum+secondnum;
break;
case '-':
printf("\nNow please input the two variables.\n");
scanf("%f", &firstnum);
scanf("%f", &secondnum);
answer = firstnum-secondnum;
break;
case '*':
printf("\nNow please input the two variables.\n");
scanf("%f", &firstnum);
scanf("%f", &secondnum);
answer = firstnum*secondnum;
break;
case '/':
printf("\nNow please input the two variables.\n");
scanf("%f", &firstnum);
scanf("%f", &secondnum);
answer = firstnum/secondnum;
break;
case 'sine':
printf("\nPlease enter the angle.\n");
scanf("%f", &angle);
answer = sin(angle);
break;
default: printf("Sorry, that is an incorrect function. The only available choices are +, -, *, /, sine.");
break;
}
printf("Your answer is %f \n", answer);
printf("\nWhen you are ready to quit, simply press Ctrl + C or just hit the X button in the top right.\n");
}
return 0;
}

'sine'
That is a multi-character literal. function is a single character. It's integral value is checked in the switch statement. You will likely never be able to consume a single character from the user which matches sine in the way that you are attempting to do so. Read a string (a char*) instead.
From the standard:
C99 6.4.4.4p10: "The value of an integer character constant containing more than one character (e.g., 'ab'), or containing a character or escape sequence that does not map to a single-byte execution character, is implementation-defined."

C does not have a first class string type. This means that you cannot use a switch statement for strings, you will need to use functions such as strlcmp for string comparison.
Depending on your objective (either making a calculator, or learning C) it might be wise to either switch to a different language with higher abstraction levels, or start with lower level exercises from a good C textbook.
Also, please be aware that working with strings and user input correctly in C, that is without security holes, is much more difficult than it would seem at first. If your objective is learning a language perhaps learning C++ is a better bet where you have std::string to handle your comparisons and iostreams to handle your input and output.

Related

Switch function directly goes to default. What's the issue?

I am new to C and am writing a simple code of converting temperatures. The code is still incomplete but still should give me some output
#include<stdio.h>
void main()
{
float temp;
char choice;
printf("\n 1. Celcius to Farenhite\n 2. Farenhite to Celcius\n What do you want to convert from? : ");
scanf("%c", &choice);
switch (choice)
{
case 1:
printf("Enter temperature in Celcius: ", temp );
scanf("%f", &temp);
break;
case 2:
printf("Enter temperature in Farenhite: ", temp);
scanf("%f", &temp);
break;
default:
printf("Invalid Choice");
break;
}
}
When I run this it asks "what do you want to convert from?" and shows the options. But when I enter 1 or 2, it directly prints and shows "Invalid Choice".
Pls tell me what's wrong :(
1 is 'int' and not a char.
1 and '1' are different.
This is the edited code
#include<stdio.h>
void main()
{
float temp;
char choice;
printf("\n 1. Celcius to Farenhite\n 2. Farenhite to Celcius\n What do you want to convert from? : ");
scanf("%c", &choice);
switch (choice)
{
case '1':
printf("Enter temperature in Celcius: ", temp );
scanf("%f", &temp);
break;
case '2':
printf("Enter temperature in Farenhite: ", temp);
scanf("%f", &temp);
break;
default:
printf("Invalid Choice");
break;
}
}
The number one is not the same as the digit "1". You are entering the character "1" and your switch statement is checking for the number one.
The number one is how many hearts I have. It can be written with the digit '1' but any number of other ways.
The digit '1' is a character. It is sometimes use to represent the number one but can also be used for other things. A variable of type char can hold the digit 1 since digits are characters.
Your switch statement is checking for the number one. You want to check for the character 1.
'1' is a character, whereas 1 is an integer. Your switch statement can't find a case to match with, hence it goes to default.
Is that the complete code? You're not converting anything here, you're only asking the user for the temperature and storing it in a variable.
OT: Indent properly, your code is messy and difficult to read. And do not use scanf for taking input. You may want to check out this link http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html.
This is a common misunderstanding for novices and occasional typo for experienced programmers(*).
1 means "the integer value one" (it is the integer literal for the value of 1).
Assuming your on an ASCII compatible platform(**) that is the character with ASCII code 1 (the non-printing character called Start of Header - SOH).
The ASCII Code for the character 1 is actually 49. But you should write:
case '1':
Because those apostrophes identify the 1 as the character representing 1 not the numeric value of 1.
The compiler will interpret '1' as actually meaning character of 1 meaning the (codepoint) value of 49.
In C char has a deeply dual role as a numeric type and as the smallest unit of text and accidental mixing of those roles causes endless confusion.
Arguably char has 3 roles. The smallest arithmetic type, the smallest unit of text (a character) and the unit of addressable memory (byte).
There are historical reasons why those roles are conflated in C.
(*) But I can't find a good answer for it even though there should be thousands of times this has been asked.
(**) C does not specify a character set but if you working on a platform that isn't ASCII compatible you will know about it. Unless you've found something in your Grandparent's basement and they're sadly not around to explain it. This footnote exists for the likely comments to the effect that C doesn't specify a character set.
Your program reads a byte from stdin and compares that to the values 1 and 2. It is unlikely the user can type these byte values as they correspond to control characters CtrlA and CtrlB1. The byte values representing the digits 1 and 2 typed by the user are noted in C as '1' and '2'. These are called character constants and are int values for the encoding of the corresponding characters.
Furthermore, you should:
indent your code more consistently.
define main with a return type int
test the return value of scanf()
fix the spelling of Fahrenheit, named after German physicist Daniel Gabriel Fahrenheit and Celsius, named after Swedish astronomer Anders Celsius.
1: From a unix terminal, one can actually enter these byte values by hitting CtrlV CtrlA and CtrlV CtrlB, respectively, followed by Enter.
Here is a modified version:
#include <stdio.h>
int main() {
float temp;
char choice;
printf(" 1. Celsius to Fahrenheit\n"
" 2. Fahrenheit to Celsius\n"
" What do you want to convert from? ");
if (scanf(" %c", &choice) != 1)
return 1;
switch (choice) {
case '1':
printf("Enter temperature in Celsius: ", temp);
if (scanf("%f", &temp) != 1)
return 1;
printf("%g degrees Celsius is %g degrees Fahrenheit\n",
temp, 32 + temp * 9 / 5);
break;
case '2':
printf("Enter temperature in Fahrenheit: ", temp);
if (scanf("%f", &temp) != 1)
return 1;
printf("%g degrees Fahrenheit is %g degrees Celsius\n",
temp, (temp - 32) * 5 / 9);
break;
default:
printf("Invalid choice\n");
break;
}
return 0;
}

Why is my program not working when I change the order of inputs? [duplicate]

This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed last year.
I started learning C and tried to code this math program using switch statements. The program runs and works just fine when I scan the operator first and then scan the numbers. But if I switch the order of the scanf functions to take the numbers first and then the operators, the program takes the number but after that it does not take the second input (the operator) and just prints the default value (invalid input). Why is this happening?
I have provided the code (if I run this code, the problem occurs with the program just taking the numbers and not taking the operators. But of the order is flipped, it works).
#include <stdio.h>
int main()
{
float a, b, result;
char operator;
printf("Enter 2 numbers:");
scanf("%f %f", &a, &b);
printf("Choose a math operator (+, -, *, /):");
scanf("%c", &operator);
switch (operator)
{
case '+':
result = a + b;
break;
case '-':
result = a - b;
break;
case '*':
result = a * b;
break;
case '/':
result = a / b;
break;
default:
printf("\nInvalid operator");
return -1;
}
printf("%f", result);
return 0;
}
The format string "%c" will read the newline character from the first line of input. What you want instead is " %c" which will skip leading whitespace, so replace the line
scanf("%c", &operator);
with
scanf(" %c", &operator);
See also https://pubs.opengroup.org/onlinepubs/9699919799/
A directive composed of one or more white-space characters shall be
executed by reading input until no more valid input can be read, or up
to the first byte which is not a white-space character, which remains
unread.
you need to change
scanf("%c", &operator);
to
scanf("%s", &operator);
it will run.

What is the best way to apply an arithmetic expression to 2 binary numbers provided by the user in C?

I am writing a program that accepts 2 binary numbers from the user. Then the user selects a arithmetic expression (+ - / * %) to apply to the numbers. I have the general input code but am at a loss as to where to go next. I'm fairly new to the C language. Here is what I have so far.
#include <stdio.h>
int main(){
int number1, number2;
char expression;
//Basic instructions at the beginning of the program
printf("This is a program to execute arithmetic in binary.\n");
printf("The program will ask you for input in the form of two binary numbers separated byan arithmetic expression (+ - / * %).\n");
printf("The binary numbers must be only 1's and 0's and a maximum of seven digits.\n");
printf("You may exit the program by typing 'exit'.\n");
//Obviously an incomplete do statement, need a loop
do {
//Getting input from the user
printf("\nEnter first binary number: ");
scanf("%d", &number1);
printf("Enter second number: ");
scanf("%d", &number2);
printf("Which expression would you like (+ - / * %): ");
scanf("%c", &expression);
}
}
Since expression is a char(and not char[]), you can use switch-case:
int result;
switch(expression){
case '+':
result=number1+number2;
break;
case '-':
result=number1-number2;
break;
case '*':
result=number1*number2;
break;
case '/':
result=number1/number2;
break;
}
You might also want to add a default, in case the user entered an invalid operator.

C - scanf didn't stop for user input

I want to get the user input for variable L, but the scanf function is not working, and the program will jump and print the next cost statement and exit if I try to input anything.
I am new to C, and hope can get some help here. Thanks. Code below:
#include <stdio.h>
#include <conio.h>
int main()
{
float L = 0; // L is litre
float gallon;
gallon = 3.785 * L;
char x[2] = {'u', 'd'}; // u is unleaded and d is diesel
float cost;
printf("Hello, welcome to PetrolUpHere!!\n");
printf("Would u like unleaded or diesel fuel?");
scanf("%s", &x[2]);
printf("Enter the litre you want to fuel:");
scanf("%.2f", &L); //SCANF NOT WORKING
switch (x[2]) {
case 'u':
cost = 1.98 * gallon;
printf("The cost is :%.2f ", cost);
break;
case 'd':
cost = 1.29*gallon;
printf("The cost is :%.2f ",cost);
break;
}
getch();
return 0;
}
There are a number of problems here:
scanf("%s", &x[2]);
I imagine you wanted to read a string into the variable x. Instead, you're saying "read a string into memory 2 positions past where x points". In this case that memory will be out of bounds. You should do this, since you only care about one character:
char input;
scanf("%c", &input);
Your switch statement is similarly broken; x[2] is again out of bounds. Use input from the above code instead.
As others have pointed out, using %.2f is not what you want to do when reading in L. Use %f instead. Generally you should only do something like that with format specifiers when printing out variables, rather than reading them in. Eventually you won't be using scanf anyway, since it's not a particularly safe way of getting input.
Finally: it seems like your understanding of how C strings work is shaky at best. This is understandable, since this is a fairly confusing topic for anyone who hasn't worked in C before, and especially for novice programmers. Here's one explanation; I'm sure you can find many more, probably better ones if you look.
There are three problems in this much of your code (at least):
char x[2] = {'u', 'd'};//u is unleaded and d is diesel
float cost;
printf("Hello, welcome to PetrolUpHere!!\n");
printf("Would u like unleaded or diesel fuel?");
scanf("%s", &x[2]);
printf("Enter the litre you want to fuel:");
scanf("%.2f", &L); //SCANF NOT WORKING
switch (x[2]) {
x is an array of 2 char which is initialized, but is not a null terminated string.
You use scanf("%s", &x[2]), which is reading a string into data that is not part of the array x.
You then dereference x[2] in the switch statement — again accessing data that is out of bounds.
You don't check either scanf() call to ensure it was able to scan a result.
You don't print what you read immediately after you read it.
The . in the scanf() format is not valid; use "%f" (you probably do not want to use "%2f" as that would limit you to two digits maximum).
You haven't actually said what you entered in response to the 'unleaded or diesel' question.
scanf("%s", &x[2]);
Should be:
scanf("%c", &x[2]);
scanf("%.2f", &L);
Should be:
scanf("%2f", &L);
And you initialized gallon with '0.0',then your output will always be '0.0'.
Hope it works.

Why is the following program stuck in a loop?

I wrote a solution to an exercise that asks to write a program that acts as a simple "printing" calculator, and also detects division by zero and checks for unknown operators.
The program works as intended when expected operators are entered. For example:
"100 S" prints "= 100.000000"
"2 /" prints "= 50.000000"
"10 *" prints "= 500.000000"
It also detects division by zero and unknown operators.
However, when I enter operators in wrong order, like this:
"/ 2" or "* 10", the program is stuck in a loop.
How do I fix this bug so that when the operators are entered in wrong order, it just prints "Unknown operator"?
// Write a program that acts as a simple "printing" calculator
#include <stdio.h>
int main (void)
{
float acc, b;
char operator;
printf ("Begin Calculations\n");
while ( operator != 'E') {
scanf ("%f %c", &b, &operator);
switch (operator)
{
case 'S': // set accumulator
case 's':
acc = b;
printf ("= %f\n", acc);
break;
case 'E': // end program
case 'e':
printf ("= %f\nEnd of Calculations.\n", acc);
break;
case '+':
printf ("= %f\n", acc += b);
break;
case '-':
printf ("= %f\n", acc -= b);
break;
case '*':
printf ("= %f\n", acc *= b);
break;
case '/':
if ( b == 0 )
printf ("Can't divide by zero.\n");
else
printf ("= %f\n", acc /= b);
break;
default:
printf ("Unknown operator.\n");
break;
}
}
return 0;
}
Update: I've found a solution
while ( operator != 'E' && operator != 'e' ) {
if ( scanf ("%f %c", &b, &operator ) < 2 ) {
printf ("Error. You need to enter a number.\n");
break;
}
else {
switch (operator)...
The result of scanf is the number of fields assigned. If scanf returns 0, it will return 0 for the same format string every time you call it. Because scanf pushes back the last character it read that does not match the input sequence (%f), it will repeatedly try to convert the same string over and over.
That's why you loop infinitely. You might want to check the result of scanf. If it's less than 2, error out.
I think you would need to make your input routine more robust than scanf (apparently) is. For example, if you read your input in whole lines, you can parse them (say, using sscanf) to get the components w/o mucking up the input stream.
scanf is reading until it can parse a floating point number. Try using gets to read in a string and then parse that string from there.
http://www.cplusplus.com/reference/clibrary/cstdio/gets/
I guess that to exit you need to enter a float + 'E' (0.0 E) and not just 'E'. Would that be what you're asking about?
Ah! I see you mentioned placing things backward. Yes. scanf() is never going to detect that.
If you're under Linux, check out lex and yacc (or flex and bison to be precise.) To do things like these, it's a lot better and you can make things a lot better (support parenthesis, minus and plus operator, instead of just add and subtract, etc.)
It's not "stuck in a loop", it's waiting for the operator that this line:
scanf ("%f %c", &b, &operator);
promises. That line reads until it receives a floating-point number, and then it reads an operator. If you give it an operator first, it will simply ignore it.
(By the way, you should initialize operator to something specific before getting to the line while ( operator != 'E') {, because for all you know, operator might happen to start out as 'E'. Also, as Mysticial says, operator isn't a great name for a C identifier, because of its uses in C++.)
The problem is that scanf() is trying to read what you told it to, that is, a floating point number and a character. When you type the other way around scanf returns because its not the format you told it too, but unfortunately it WONT flush the buffer, so the while would go again and scanf tries to read again, and so on.
Drop scanf, although if this is only for a homework you may try doing:
if (!scanf ("%f %c", &b, &operator)) {
scanf ("%*[^\n]"); /* TRY to flush stdin */
printf("Incorrect input!");
incorrect_input++;
continue;
} else {
incorrect_input = 0;
}
if (incorrect_input > 5) {
break; /* Very simple measure to avoid getting stuck in the loop */
}
However, when I enter operators in wrong order, like this: "/ 2" or "* 10", the program is stuck in a loop.
How do I fix this bug so that when the operators are entered in wrong order, it just prints "Unknown operator"?
You might want to read the entire expression and then parse it for correctness. There are various expression notation methods (infix, postfix (also known as reverse polish notation) and prefix (otherwise known as polish notation)) which makes the task of validating and evaluating them easier.
Also if you have or can get hold of the "The C Programming Language" book written by Dennis Ritchie and Brian Kernighan, turn to chapter 4 and read the section that walks you through the design and implementation of a calculator program.

Resources