Why won't my result update after the first iteration(?) - c

#include <stdio.h>
#include <math.h>
void scan_data(char *op, float *operand);
float do_next_op(char op, float operand, float *accumulator);
int main(void)
{
char op;
float operand;
float accumulator = 0;
do
{
printf(" + add\n - subtract\n * multiply\n / divide\n ^ power\n q quit\n\n");
scan_data(&op, &operand);
if(op == 'q' || op == 'Q')
{
printf("Final result is %.1f\n", do_next_op(op, operand, &accumulator));
break;
}
else
{
printf("result so far is %.1f\n", do_next_op(op, operand, &accumulator));
}
}while(op != 'q' || op == 'Q');
}
void scan_data(char *op, float *operand)
{
scanf("%c%f",op, operand);
}
float do_next_op(char op, float operand, float *accumulator)
{
switch(op)
{
case('+'):
*accumulator = *accumulator + operand;
break;
case('-'):
*accumulator = *accumulator - operand;
break;
case('*'):
*accumulator = *accumulator * operand;
break;
case('/'):
*accumulator = *accumulator / operand;
break;
case('^'):
*accumulator = pow(*accumulator,operand);
break;
}
return *accumulator;
}
I'm trying to code a "simple" calculator where if i type
+5.0
result so far is 5.0
^2
result so far is 25.0
/ 2.0
result so far is 12.5
Q 0
final result is 12.5
The problem is, the code will "correctly" output the first operation but if i put anymore operation after that I doesn't update to the new value.
How can I fix the code to do what I intend to do?
I'm sorry in advance if my question wording and format is off, I don't know how to ask it in a proper way.

the problem is in the statement:
scanf("%c%f",op, operand);
After the first iteration, there is a left over newline in stdin
That newline is a 'white space', typically \n
That 'white space must be consumed before the %c rather than the %c consuming it. Suggest:
scanf(" %c%f",op, operand);
where the leading space in the format string consumes that 'white space'
regarding the statement:
*accumulator = pow(*accumulator,operand);
the pow() function expects to be working with double values, not float values. Suggest:
*accumulator = powf(*accumulator,operand);
Notice this is calling powf() not pow()

Related

Why does changing the type from float to double make this comparison work?

If I just change the data type float to double in the following program, the code works fine for input 14.2 (and all inputs). However, if I use float instead of double, the program behaves strangely that, it works fine for all inputs EXCEPT 14.2!
#include <stdio.h>
#include <ctype.h>
void totalPrice(char, float);
int main()
{
char gasStation;
float tankSize;
printf("Enter the gas station: \n");
scanf("%c", &gasStation);
gasStation = toupper(gasStation);
printf("Enter the size of the gas tank: \n");
scanf("%f", &tankSize);
totalPrice(gasStation, tankSize);
}
void totalPrice(char gasStation, float tankSize)
{
float amount;
switch(gasStation)
{
case 'I':
if (tankSize == 5)
amount = (5*75.49) + (0.09*(5*75.49)) + (0.09*(5*75.49));
else if (tankSize == 14)
amount = (14.2*75.49) + (0.09*(14.2*75.49)) + (0.09*(14.2*75.49));
else if (tankSize == 19)
amount = (19*95.50) + (0.12*(19*95.50)) + (0.12*(19*95.50));
break;
case 'B':
if (tankSize == 5)
amount = (5*77.50) + (0.09*(5*77.50)) + (0.09*(5*77.50));
else if (tankSize == 14.2)
amount = (14.2*77.50) + (0.09*(14.2*77.50)) + (0.09*(14.2*77.50));
else if (tankSize == 19)
amount = (19*97.50) + (0.12*(19*97.50)) + (0.12*(19*97.50));
break;
case 'H':
if (tankSize == 5)
amount = (5*79.50) + (0.09*(5*79.50)) + (0.09*(5*79.50));
else if (tankSize == 14.2)
amount = (14.2*79.50) + (0.09*(14.2*79.50)) + (0.09*(14.2*79.50));
else if (tankSize == 19)
amount = (19*99.50) + (0.12*(19*99.50)) + (0.12*(19*99.50));
break;
default:
printf("Unable to read tankSize\n");
}
amount+=20; //Delivery charge
printf("Total price to be paid for refilling the gas (including GST) is INR: %f", amount);
}
Above code doesn't work.
However, changing the data type of tankSize, amount, and the second parameter to totalPrice to double from float cause the code to work.
Why do the integer inputs (5 and 19) work in all cases but input 14.2 works only when data type is double?
In this if statement
else if (tankSize == 14.2)
you are comparing a float number stored in the variable tankSize of the type float with a double constant 14.2.
Double values have higher precision than float values.
You should compare two float values
else if (tankSize == 14.2f)
Using the suffix f makes the floating constant of the type float.
From the C Standard (6.4.4.2 Floating constants)
4 An unsuffixed floating constant has type double. If suffixed by the
letter f or F, it has type float. If suffixed by the letter l or L, it
has type long double.
That is instead of the floating constant 14.2 of the type double you should use the floating constant 14.2f of the type float.
Here is a demonstration program
#include <stdio.h>
int main( void )
{
float tankSize;
printf( "Type 14.2: " );
scanf( "%f", &tankSize );
if (tankSize == 14.2)
{
puts( "tankSize is equal to double 14.2." );
}
else
{
puts( "tankSize is not equal to double 14.2." );
}
if (tankSize == 14.2f )
{
puts( "tankSize is equal to float 14.2f." );
}
else
{
puts( "tankSize is not equal to float 14.2f." );
}
}
The program output is
Type 14.2: 14.2
tankSize is not equal to double 14.2.
tankSize is equal to float 14.2f.

Builidng a calculator in c language can use a previous result

i got problem with this calculator which i need to use the previous result of previous operartion (if i want to ) but when i do it it gives correct if only give it the same previous operation
here is the code :
#include<stdio.h>
#include<math.h>
double addition (double a, double b)
{
double add;
add=a+b;
return add;
}
double soustraction (double a, double b)
{
double sous;
sous=a-b;
return sous;
}
double multiplication (double a,double b)
{
double multi;
multi=a*b;
return multi;
}
double division (double a, double b)
{
double div;
div=a/b;
return div;
}
double reste_de_division (int a,int b)
{
double rest;
rest=a%b;
return rest;
}
double puissance( double a,double b)
{
int i;
double r;
i = 0;
r = 1;
while (i < b){
r = r * a;
i ++;
}
return r;
}
double factorielle (double a)
{
int i;
double facto;
facto=1;
for(i=0;i<a;i++)
{facto=(a-i)*facto;
}
return facto;
}
double PGCD (int a,int b)
{
int i;
double pgcd;
for(i=1; i <= a && i <= b; ++i)
{
if(a%i==0 && b%i==0)
pgcd = i;
}
return pgcd;
}
double PPCM (int a,int b)
{
int ppcm;
ppcm = (a > b) ? a : b;
while(ppcm%a !=0 || ppcm%b !=0)
ppcm=ppcm+1;
return ppcm;
}
double inverse (double a)
{
double inv;
inv=1/a;
return inv;
}
int main(){
double a,b,r;
char ch;
printf("\n***************************************\n");
printf (" \n + Addition \t \t - Subtraction \n * Multiplication \t / Division \n Reste de division \t c Puissance \n ! Factorielle \t \t g PGCD \n p PPCM \t \t i Inverse \n q Quitter \n");
printf("\n***************************************\n");
printf("Donner les deux nombres et l'operation:\n");
do
{b=r;
scanf("%lf %lf %c",&a,&b,&ch);
switch (ch)
{case '+':
r=addition(a,b);
printf("%lf\n",r);
break;
case '-':
r=soustraction(a,b);
printf("%lf\n",r);
break;
case '*':
r=multiplication(a,b);
printf("%lf\n",r);
break;
case '/':
r=division(a,b);
printf("%lf\n",r);
break;
case '%':
printf("%lf\n",reste_de_division(a,b));
break;
case 'c':
printf("%lf\n",puissance(a,b));
break;
case '!':
printf("%lf\n",factorielle(a));
break;
case 'g':
printf("%lf\n",PGCD(a,b));
break;
case 'p':
printf("%lf\n",PPCM(a,b));
break;
case 'i':
printf("%lf\n",inverse(a));
break;
}
}while(ch !='q');
return 0;
}
Sorry for my bad english
example:
5 6 +
11
6 +
17
3 -
20 //this is error, it's supposed to give 14 not 20
Your problem is here:
scanf("%lf %lf %c",&a,&b,&ch);
You expect the user to always input two doubles and one character. If the user only gives one double and one character, the value of ch (and b) is unchanged and the program will do the same operation as it did the last time.
Example:
First input:
5 6 +
This will make a equal 6, b equal 5 and ch equal +. Consequently the program will add the two numbers 5 and 6 and produce the result 11 which is stored in b.
Next input:
1 -
This will make a equal one but leave both b and ch unchanged, i.e. b is still equal 11 and ch is still equal +. Consequently the program will add the two numbers 1 and 11 and produce the result 12 which is stored in b.
This is just one example of things that can go wrong when doing scanf("%lf %lf %c",&a,&b,&ch); There are other input sequences that will lead to (even more) bizar output.
You need a much more strict parsing of user input. The scanf functions isn't good for that. Consider using fgets to read a whole line and the parse it afterwards. With care that can be done using sscanf.

Storing arithmetic operators in an array in C?

I am just wondering if it is possible to store the basic arithmetic operators (+, -, *, /) inside variables in C. The reason that I need to do this is because I am trying to build a basic calculator program that accepts up to 5 numbers and can do any of these operations on them. Right now the only way that I have been able to come up with to do this is to store the operators inside a char array and then iterate through it using for loops and switch statements to decide what operator to use for each step. It's pretty clunky and doesn't actually work right now and I am not sure why. Also even if it did work, it wouldn't follow order of operations which I need it to do as well.
This is an example of the output of my program:
Enter a number: 4
Enter an operator (+, -, *, /, or =): +
Enter a number: 8
Enter an operator (+, -, *, /, or =): -
Enter a number: 7
Enter an operator (+, -, *, /, or =): *
Enter a number: 9
Enter an operator (+, -, *, /, or =): /
Enter a number: 2
4.00 + 8.00 - 7.00 * 9.00 / 2.00
0.500000
-6.500000
-6.500000
-3.250000
-3.250000
Result: -3.25
[Finished in 24.13s]
The first 9 lines are just taking the input for the numbers and operators, the 10th line prints out the numbers and operators entered in order, the 11th - 15th lines are supposed to print out the result after each operation which you can see are all incorrect, and the final line prints out the result. What do you think might be causing the math to be incorrect?
Here is my code at the moment:
#include <stdio.h>
#include <stdlib.h>
int main() {
double nums[5];
char operators[5];
double result;
int i = 0;
while ((i <= 4) && (operators[i - 1] != '=')) {
/* Getting the user's input */
printf("Enter a number: ");
scanf("%lf", &nums[i]);
if (i == 4) {
operators[4] = '=';
} else {
printf("Enter an operator (+, -, *, /, or =): ");
scanf(" %c", &operators[i]);
}
i++;
}
printf("%.2f %c %.2f %c %.2f %c %.2f %c %.2f\n", nums[0], operators[0], nums[1], operators[1], nums[2], operators[2], nums[3], operators[3], nums[4]);
for (i = 0; i <= 4; i++) {
/* Doing the math */
if (i == 0) {
/* Getting the value of the first two numbers */
switch(operators[i]) {
case '+' :
result = nums[0] + nums[1];
case '-' :
result = nums[0] - nums[1];
case '*' :
result = nums[0] * nums[1];
case '/' :
result = nums[0] / nums[1];
}
printf("%f\n", result);
} else {
/* Iterating through the rest of both arrays and
continuing to perform operations on the result */
switch(operators[i]) {
case '+' :
result = result + nums[i + 1];
case '-' :
result = result - nums[i + 1];
case '*' :
result = result * nums[i + 1];
case '/' :
result = result / nums[i + 1];
}
printf("%f\n", result);
}
}
// Printing out the answer rounded to 2 decimal points
printf("Result: %.2f", result);
return 0;
}
So just to re-iterate my question, is there a way that I could store the operators in a variable as operators instead of chars, which would remove the need for all of the loops, if statements, and switch statements, and if not, what changes should be made to make my code work properly?
P.S. I am only just learning C right now so suggestions for how I should be formatting my code are welcome too.
First the bugs:
while ((i <= 4) && (operators[i - 1] != '=')) {
On the first iteration of this loop i is 0 so operators[i - 1] attempts to read before the start of the array. Reading outside of array bounds is undefined behavior.
The incorrect values you're getting is because there's no break statement between each of your switch cases. Without that, the code "falls through" to the next case. So if the operation is subtraction you do that, then multiplication, then division.
Regarding the operators, you can create functions to encapulate each operator, each with the same signature (i.e. return type and number/type of parameters) along with a matching typedef. Then you can have an array of pointers to these functions, and set them to point to the proper function.
Also, you don't need to have a special case for the first set of operators. Just start from index 1 instead of 0 and initialize the result to the first value.
#include <stdio.h>
#include <stdlib.h>
double op_add(double x, double y)
{
return x + y;
}
double op_sub(double x, double y)
{
return x - y;
}
double op_mul(double x, double y)
{
return x * y;
}
double op_div(double x, double y)
{
return x / y;
}
typedef double (*op_type)(double, double);
int main() {
double nums[5];
char operator;
op_type operators[5];
double result;
int i = 0;
while (i < 5) {
/* Getting the user's input */
printf("Enter a number: ");
scanf("%lf", &nums[i]);
if (i == 4) {
operators[i] = NULL;
} else {
printf("Enter an operator (+, -, *, /, or =): ");
scanf(" %c", &operator);
switch(operator) {
case '+' :
operators[i] = op_add;
break;
case '-' :
operators[i] = op_sub;
break;
case '*' :
operators[i] = op_mul;
break;
case '/' :
operators[i] = op_div;
break;
default :
operators[i] = NULL;
break;
}
}
if (!operators[i]) break;
i++;
}
result = nums[0];
for (i = 1; i < 5; i++) {
if (operators[i-1]) {
result = operators[i-1](result, nums[i]);
printf("%f\n", result);
} else {
break;
}
}
// Printing out the answer rounded to 2 decimal points
printf("Result: %.2f", result);
return 0;
}

Calculator program requires + and - to be entered twice

I am writing a simple calculator program to add, subtract, multiply, divide and do exponential equations. The program must repeat until "q0" is entered and it must have two functions called by the main function like I have written. The problem is when I run the program the first number shows up fine and then I can multiply, divide, and do exponential functions fine but if I want to add or subtract I must enter the + or - twice for it to count it. This is the program I have written:
#include <stdio.h>
#include <math.h>
void scan_data(char *oprter, double *oprand);
void do_next_op(char oprter, double oprand, double *accum);
int
main(void)
{
double nmber, /* input/output - operand */
total; /* output - final result */
char sign; /* input/output - operator */
total = 0;
do {
scan_data(&sign, &nmber);
do_next_op(sign, nmber, &total);
} while (sign != 'q');
printf("Final result is %.2f", total);
return (0);
}
/*
* Gathers operator and operand to perform calculation
* Post: results are stored in cells pointed to by oprter, and oprand
*/
void
scan_data(char *oprter, /* input - amount being withdrawn */
double *oprand) /* output - number of tens */
{
double amount;
amount = 0;
scanf("%c", &*oprter);
scanf("%lf", &amount);
*oprand = amount;
}
/*
* Performs calculation and displays results
* Pre: oprter and oprand are defined
* Post: function results are stored in cell pointed to by accum
*/
void
do_next_op(char oprter,
double oprand,
double *accum)
{
double tot_amount;
tot_amount = *accum;
switch(oprter)
{
case '+':
tot_amount = (tot_amount + oprand);
printf("result so far is %.2f\n", tot_amount);
break;
case '-':
tot_amount = (tot_amount - oprand);
printf("result so far is %.2f\n", tot_amount);
break;
case '*':
tot_amount = tot_amount * oprand;
printf("result so far is %.2f\n", tot_amount);
break;
case '/':
tot_amount = tot_amount / oprand;
printf("result so far is %.2f\n", tot_amount);
break;
case '^':
tot_amount = pow(tot_amount, oprand);
printf("result so far is %.2f\n", tot_amount);
break;
}
*accum = tot_amount;
}
An example of what it is doing follows:
+5
result so far is 5.00
+5
-5
++5
result so far is 10.00
--5
result so far is 5.00
*2
result so far is 10.00
/2
result so far is 5.00
^2
result so far is 25.00
q0
Final result is 25.00
The problem is most likely that scanf leaves the newline in the input buffer when you do
scanf("%lf", &amount);
That means that the next call to
scanf("%c", oprter);
it will read that newline.
This can be solved by asking scanf to read and skip all leading whitespace by adding a single space to the scanf format string like
scanf(" %c", oprter);
// ^
// |
// Note space here

Intro to C: Addition and Looping

I'm continuing on my quest to mastery C and I'm currently working on an exercise to have my rudimentary calculator continuously to prompt me for two operands and a operator. If the operator is not a '+', it displays an error message. Right now, I'm running into a few problems.
When I enter '+' it shows up two times. There is NOTHING I can find in my code that indicate that this would happen.
The first operand exhibits the same problem. I also do not know how to tell my code that I am done inputting.
Second operand is fine, but I still do not know how to terminate input.
Right after it shows the results, it loops back correctly but gives me an error message before prompting again.
http://tinypic.com/r/34ew5cx/6
NOTE: I know that you use lf to read double numbers in scanf, but for some reason lf isn't working for me and f is working just fine so disregard :)
Any observations are appreciated, along with any general suggestions on how to format code/ask questions on this site/how to approach problems like this. Thanks for your help!
int main () {
char mychar;
int a;
double op1;
double op2;
printf("Welcome to Andrew Hu's calculator program!\n"); //Greeting
while(1)
{ printf("Enter a mathematical operation to perform:\n");
scanf("%c", &mychar);
if(mychar == '+') //Valid Operators
a = 1;
else
a = 0;
if(a == 0) //Operator Checker, error if invalid
printf("\nError, not a valid operator\n");
else if(a == 1){
printf("%c\n", mychar),
printf("Enter OP1:\n"),
scanf("%f", &op1),
printf("%f\n", op1),
printf("Enter OP2:\n"),
scanf("%f\n", &op2),
printf("%f\n", op2),
printf("Result of %f %c %f = %f\n",
op1, mychar, op2, (op1 + op2) );
}
}
This is a typical case where your teacher/tutor/book/online tutorial/whatever suggests that using scanf() is a good idea, whereas it really isn't. You should also not make any assumptions about line endings, and as a very last and marginal sidenote, you should structure your code better (formatting and consistency regarding curly braces included).
What I suggest you do is leave poor scanf() alone, it doesn't always do what you think it does, this is especially the case when there are single characters, strings and newline characters to read. Instead, you'd be better off reading a line and parsing and/or validating it. It will also be much simpler if you do it correctly.
I also do not know how to tell my code that I am done inputting.
Well, you decide that. How about a quit operator? Example:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main()
{
char buf[0x100] = { 0 };
while (1) {
// If the user has entered "q", we enter the loop
fgets(buf, sizeof(buf), stdin);
if (buf[0] == 'q') break;
char *end;
float op1 = strtof(buf, &end); // parse 1st operand
while (isspace(*end)) {
end++;
}
char op = *end++; // get operator
float op2 = strtof(end, NULL); // parse 2nd operand
float r;
// do the calculation
switch (op) {
case '+':
r = op1 + op2;
break;
case '-':
r = op1 - op2;
break;
case '*':
r = op1 * op2;
break;
case '/':
r = op1 / op2;
break;
default:
fprintf(stderr, "Error: invalid operator '%c'\n", op);
continue;
break;
}
// print the result
printf("%f %c %f = %f\n", op1, op, op2, r);
}
return 0;
}
First thing, you need %lf in scanf to read a double, otherwise you just read a float and store it in half the double...
scanf("%lf", &op1),
This is not needed for printf because every float argument is first promoted to double...

Resources