3 Pointers in 1 Function - Calculator doesn´t work - c

I've a problem with a function in my calculator-program. The function returns me back only 0 values​​. I want that:
Input:3+4
Output:7
I have worked with pointers to use the call by reference method. Please give me some tips.
The mistake is in the function readcalc. If I write the whole syntax in the main program it works.
Here is my code.
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
double readcalc(double*,char*,double*);
double addition(double,double);
double subtraction(double,double);
double multiplication(double,double);
double division(double,double);
int main()
{
double a=0, b=0;
char op='R', restart = 'Y';
while (restart != 'N')
{
readcalc(&a,&op,&b);
printf("%lf%lf", a, b);
printf("\n ---CALCULATOR--- \n\n\n");
switch (op)
{
case '+':printf("%lf + %lf = %lf\n", a, b, addition(a, b)); break;
case '-':printf("%lf - %lf = %lf\n", a, b, subtraction(a, b)); break;
case '*':printf("%lf * %lf = %lf\n", a, b, multiplication(a, b)); break;
case '/':printf("%lf / %lf = %lf\n", a, b, division(a, b)); break;
default:printf("bad operator!");
}
printf("New Calc? (Y,N) \n");
fflush(stdin);
scanf("%c", &restart);
if (restart != 'Y'&&restart != 'N')
{
printf("Bad input!");
}
}
fflush(stdin);
getchar();
return 0;
}
double readcalc(double* x,char* opp,double* y)
{
printf("\n Type your calculation!(z.B.4+7)\n");
scanf("%lf%c%lf", &x, &opp, &y);
return 0;
}
double addition(double a,double b)
{
double c = 0;
c = a + b;
return c;
}
double subtraction(double a, double b)
{
double c = 0;
c = a - b;
return c;
}
double multiplication(double a, double b)
{
double c = 0;
c = a*b;
return c;
}
double division(double a, double b)
{
double c = 0;
c = a / b;
return c;
}
What can I change?

The problem with readcalc is that you pass the pointer to the pointer as argument to scanf. The variables are already pointers, so you don't have to use the address-of operator to get a pointer, as then you get pointers to the pointers.
Also be careful with the scanf format, as the "%c" format doesn't skip leading whitespace, so if you enter e.g. 1 +2 then the scanf call will not be able to read the operator or the second number.

void readcalc(double* x,char* opp,double* y)
{
printf("\n Type your calculation!(z.B.4+7)\n");
scanf("%lf%c%lf", x, opp, y); // <== no &'s
}

Your readcalc function invokes
scanf("%lf%c%lf", &x, &opp, &y);
on pointers, int *x, etc...
When you place it inline in main, it works on the addresses of the variables.
Change it to
scanf("%lf%c%lf", x, opp, y);
At a suitable warning level, you may have seen warning.
While you are there, readcalc returns a double, which you never use. Perhaps it should simply be void?

Related

How NOT to read float type in scanf when reading type int

I need to write two integers (and nothing else) to variables. It does the validation makes sure that none of args is a string and that they are not empty and excepts division by zero, or when i put float as a first arg but when i put float as a second argument it does not makes an exception. How can i solve it using only stdio.h?
#include <stdio.h>
void sum(int a, int b);
void dif(int a, int b);
void prod(int a, int b);
void qut(int a, int b);
int main() {
int x, z;
int digits = scanf("%d %d", &x, &z);
if (digits != 2) {
printf("n/a\n");
return 2;
}
else {
sum(x, z);
dif(x, z);
prod(x, z);
qut(x, z);
}
return 0;
}
void sum(int a, int b) {
printf("%d ", a + b);
}
void dif(int a, int b) {
printf("%d ", a - b);
}
void prod(int a, int b) {
printf("%d ", a * b);
}
void qut(int a, int b) {
if (a == 0 || b == 0) {
printf("n/a\n");
}
else {
printf("%d\n", a / b);
}
}
Sorry, i understand that the code is quiet simple and my question is quiet dumb :)
Thx!
As mentioned in the comments, scanf is the WRONG TOOL for this job. scanf is notoriously bad at error handling.
Theoretically it's possible — barely possible — to solve this problem using scanf. By the same token, it's possible to drive a screw into a piece of wood using a hammer. But it's a terrible idea. A woodshop teacher who taught his students to drive screws using a hammer would be fired for incompetence. But for some reason we tolerate this kind of incompetence in teachers of beginning programming.
Normally I don't do homework problems here; normally that's a bad idea, too; normally it makes much more sense to have you, the student, do the work and acquire the learning. In the case of boneheaded assignments like this one, though, I have no qualms about giving you a fully-worked-out solution, so you can get your incompetent instructor off your back and go on to learn something more useful. Here is the basic idea:
Read a line of text (a full line), using fgets.
Parse that line using sscanf, ensuring that it contains a number and a number, and nothing else.
Specifically, we'll use %d to read the first integer, and %d to read the second integer, and then we'll use a third %c to pick up whatever character comes next. If that character is anything other than the \n that marks the end of the line, it indicates that the user has typed something wrong, like a string, or the . that's part of a floating-point number.
This is basically the same as user3121023's solution.
int main()
{
char line[100];
int x, z;
char dummy;
if(fgets(line, sizeof(line), stdin) == NULL) return 1;
int digits = sscanf(line, "%d%d%c", &x, &z, &dummy);
if(digits < 2 || digits > 2 && dummy != '\n') {
printf("n/a\n");
return 2;
}
...
See also What can I use for input conversion instead of scanf?
Footnote: The code here has one unfortunate little glitch: If the user types a space after the second number, but before the newline, the code will reject it with n/a. There are ways to fix that, but in my opinion, for this exercise, they're just not worth it; they fall under the "law of diminishing returns". If your users complain, just act like incorrigible software vendors everywhere: remind them that they were supposed to type two numbers and nothing else, and the space they typed after the second number is "something else", so it's THEIR FAULT, and not your bug. :-)
After scanning for the integers, use a loop to scan for one whitespace character. Break out of the loop on a newline.
For any other character, the scan will return 0.
#include <stdio.h>
void sum(int a, int b);
void dif(int a, int b);
void prod(int a, int b);
void qut(int a, int b);
int main() {
char ws[2] = ""; // whitespace
int scanned = 0;
int x, z;
int digits = scanf("%d %d", &x, &z);
if (digits != 2) {
printf("n/a\n");
return 2;
}
while ( ( scanned = scanf( "%1[ \t\n]", ws))) { // scan for 1 whitespace
if ( scanned == EOF) {
fprintf ( stderr, "EOF\n");
return 1;
}
if ( ws[0] == '\n') {
break;
}
}
if ( scanned != 1 || ws[0] != '\n') {
printf("n/a\n");
return 3;
}
else {
sum(x, z);
dif(x, z);
prod(x, z);
qut(x, z);
}
return 0;
}
void sum(int a, int b) {
printf("%d ", a + b);
}
void dif(int a, int b) {
printf("%d ", a - b);
}
void prod(int a, int b) {
printf("%d ", a * b);
}
void qut(int a, int b) {
if (a == 0 || b == 0) {
printf("n/a\n");
}
else {
printf("%d\n", a / b);
}
}

Returns a value as an output parameter

I have a question in C where I need to insert coefficients of a quadratic equation into a function and return the number of solutions and result.
Write a program that accepts a series of 3 real numbers, which are the
coefficients of a quadratic equation, and the program will print out
some solutions to the equation and the solutions themselves.
Guidelines:
Functions must be worked with one of the functions that
returns the number of solutions as a returned value, and returns the
solutions themselves through output parameters.
3 numbers must be
received each time. The input will be from a file (will end in EOF)
In the meantime I built the function without reading from a file just to see that it works for me, I built the function that returns the number of solutions but I got entangled in how to return the result as output parameter
here is my code for now:
int main ()
{
double a, b, c, root1,root2,rootnum;
printf("Enter coefficients a, b and c: ");
scanf("%lf %lf %lf",&a, &b, &c);
rootnum=(rootnumber(a,b,c);
printf("the number of roots for this equation is %d ",rootnum);
}
int rootnumber (double a,double b, double c)
{
formula=b*b - 4*a*c;
if (formula<0)
return 0;
if (formula==0)
return 1;
else
return 2;
}
In C, providing an "output parameter" usually amounts to providing an argument that is a pointer. The function dereferences that pointer and writes the result. For example;
int some_func(double x, double *y)
{
*y = 2*x;
return 1;
}
The caller must generally provide an address (e.g. of a variable) that will receive the result. For example;
int main()
{
double result;
if (some_func(2.0, &result) == 1)
printf("%lf\n", result);
else
printf("Uh oh!\n");
return 0;
}
I've deliberately provided an example that illustrates what an "output parameter" is, but has not relationship to the code you actually need to write. For your problem, you will need to provide two (i.e. a total of five arguments, three that you are providing already, and another two pointers that are used to return values to the caller).
Since this is a homework exercise, I won't explain WHAT values your function needs to return via output parameters. After all, that is part of the exercise, and the purpose is for you to learn by working that out.
Apart from a wayward parenthesis in the call and some other syntax errors, what you have so far looks fine. To print out the number of roots, you need to put a format specifier and an argument in your printf statement:
printf("the number of roots for this equation is %d\n", rootNum);
The %d is the format specifier for an int.
Here is your working code:
#include <stdio.h>
int rootnumber (double a,double b, double c)
{
double formula = (b*b) - (4*(a)*(c));
if (formula > 0) {
return 2;
}
else if (formula < 0) {
return 0;
}
else {
return 1;
}
}
int main (void)
{
double a, b, c;
printf("Enter coefficients a, b and c: ");
scanf("%lf %lf %lf",&a, &b, &c);
printf("The number of roots for this equation is %d ", rootnumber(a,b,c));
return 0;
}
It just need some sanity checking, its working now:
#include<stdio.h>
int rootnumber(double a, double b, double c);
int main ()
{
double a, b, c, root1,root2;
int rootnum;
printf("Enter coefficients a, b and c: ");
scanf("%lf %lf %lf",&a, &b, &c);
rootnum=rootnumber(a,b,c);
printf("the number of roots for this equation is %d", rootnum);
return 0;
}
int rootnumber(double a, double b, double c)
{
int formula= (b*b) - (4*a*c);
if (formula<0)
return 0;
if (formula==0)
return 1;
else
return 2;
}

Argument expects double but I need floats?

I'm writing a quadratic equation root solver for class. I either get %f expects argument type double but arguments 2 and 3 have type float on lines 45 and 51, or I get -nan and-inf as an answer when I get it to compile. I can't figure out any other way to get it to work. I cannot use doubles on this. Only floats and ints with the sub programs.
#include <stdio.h>
#include <math.h>
void solve_linear(int, int);
void solve_quad(int, int, int);
void solve_real(int,int, int);
void solve_complex(int, int, int);
int main (int argc, char *argv[]){
int a, b, c;
if (argc==4) {
sscanf(argv[1], "%d", &a);
sscanf(argv[2], "%d", &b);
sscanf(argv[3], "%d", &c);
if (a=0){
if (b=0){
printf("Error. A and B cannot both be 0\n");
}
else solve_linear(b, c);
}
else solve_quad(a,b,c);
}
else printf("Error. Must enter 3 numbers on command line.\n");
}
void solve_linear(b, c){
float root;
root=(float)-c/b;
printf("%f\n", root);
}
void solve_quad(a, b, c){
if(b*b-4*a*c<0){
solve_complex(a,b,c);
}
else{
solve_real(a, b, c);
}
}
void solve_real(a, b, c){
float x1, x2;
x1=(-b+sqrt(b*b-4*a*c))/(2*a);
x2=(-b-sqrt(b*b-4*a*c))/(2*a);
printf("%f, %f\n", &x1, &x2);
}
void solve_complex(a, b, c){
float x_real, x_img;
x_real=-b/(2.0*a);
x_img=(sqrt(abs(b*b-4*a*c)))/(2*a);
printf("%f + %fi\n", &x_real, &x_img);
}
As soon as you call printf, all float arguments are automatically converted to double. You cannot prevent this.
Enable your compiler's warnings, they will tell you that printf expects direct values instead of pointers, so the code should be printf("%f +%f = %f\n", a, b, a + b);.
This is the difference: scanf needs pointers (since it writes to the variables), pintf only needs the values themselves (so no need for pointers).

Quadratic Equation not working properly

I am new to both this site and C programming and I am attempting to make a quadratic formula but I cannot get the roots to work. I believe I am not calling a function or perhaps there is something else wrong. Any help would be appreciated, thank you!
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
float userinput(char prompt[]); //Function Prototype
float root(float a, float b, float c);
int main()
{
float a,b,c;
a=userinput("Enter the value for a:"); //Function Call
b=userinput("Enter the value for b:");
c=userinput("Enter the value for c:");
printf("The Equation you entered is |n%fx^2%+fx%+f=0", a, b, c);
return 0;
}
float root(float a, float b, float c)
{
float D,x,x1,x2,x3,x4;
D = b*b - 4*a*c;
if(D>0)
{
printf("There are two real roots, the roots are: ");
x1 = ((-b+(sqrt(D)))/(2*a));
x2 = ((-b-(sqrt(D)))/(2*a));
printf("%.2f and %.2f,x1 , x2");
}
if(D==0)
{
printf("There is one real root, the root is: ");
x = ((-b)/(2*a));
printf("%.2f,x");
}
if(D<0)
{
printf("There are two imaginary roots. The roots are: ");
x3 = ((-b/2*a)+(sqrt(fabs(D))/(2*a)));
printf("%.2f,x3i and");
x4 = ((-b/2*a)-(sqrt(fabs(D))/(2*a)));
printf("%.2f,x4i");
}
}
float userinput(char prompt[]) //Function definition
{
float answer;
int status;
do
{
printf("%s",prompt);
status=scanf("%f", &answer);
if(status!=1)
{
fflush(stdin);
printf("INPUT ERROR!\n");
}
}
while(status!=1);
return answer;
}
You never call the function root() so it will never be executed. Put the function call somewhere before return 0; of main():
root(a, b, c);
Also, fix the printf() calls as mentioned above.
I'm not sure if this will fix everything but in your code you have your print statements formatted incorrectly. For example, this line:
printf("%.2f and %.2f,x1 , x2");
Should be printf("%.2f and %.2f", x1, x2);
The variables whose values you are trying to use should be outside of the quotation marks. Hopefully this helps.
You have several errors.
You never call root().
root is declared to return float, but it doesn't return anything, it just prints the roots. It should be declared void.
You have mistakes in many of your printf() calls. When you're displaying the equation, you have |n instead of \n, and %+f instead of +%f. When you're displaying the roots, you have the variables that you want to print inside the format string, instead of as separate arguments to printf.
Here's the corrected code.
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
float userinput(char prompt[]); //Function Prototype
void root(float a, float b, float c);
int main()
{
float a,b,c;
a=userinput("Enter the value for a:"); //Function Call
b=userinput("Enter the value for b:");
c=userinput("Enter the value for c:");
printf("The Equation you entered is \n%fx^2+%fx+%f=0\n", a, b, c);
root(a, b, c);
return 0;
}
void root(float a, float b, float c)
{
float D,x,x1,x2,x3,x4;
D = b*b - 4*a*c;
if(D>0)
{
printf("There are two real roots, the roots are: ");
x1 = ((-b+(sqrt(D)))/(2*a));
x2 = ((-b-(sqrt(D)))/(2*a));
printf("%.2f and %.2f" ,x1 , x2);
}
if(D==0)
{
printf("There is one real root, the root is: ");
x = ((-b)/(2*a));
printf("%.2f",x);
}
if(D<0)
{
printf("There are two imaginary roots. The roots are: ");
x3 = ((-b/2*a)+(sqrt(fabs(D))/(2*a)));
printf("%.2fi and ", x3);
x4 = ((-b/2*a)-(sqrt(fabs(D))/(2*a)));
printf("%.2fi", x4);
}
}
float userinput(char prompt[]) //Function definition
{
float answer;
int status;
do
{
printf("%s",prompt);
status=scanf("%f", &answer);
if(status!=1)
{
fflush(stdin);
printf("INPUT ERROR!\n");
}
}
while(status!=1);
return answer;
}
DEMO

C Calculator with a lot of functions in functions in functions

I had programmed first an easy calculator. Now I would like to outsource the individual program components in Functions. The Problem is the switch-part.The program always gives me the default message:Bad operator. Please take a look and give me some tipps.Is something wrong with the pointers and double-pointers?
Here is my code:
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
void newcalc(char*,double*,char*,double*);
double switchfunk(double**, char**, double**);
double readcalc(double**,char**,double**);
double addition(double,double);
double subtraction(double,double);
double multiplication(double,double);
double division(double,double);
int main()
{
double a=0, b=0;
char op='R', restart = 'Y';
newcalc(&restart,&a,&op,&b);
fflush(stdin);
getchar();
return 0;
}
double switchfunk(double** x, char** opp, double** y)
{
printf("\n ---CALCULATOR--- \n\n\n");
switch (**opp)
{
case '+':printf("%lf + %lf = %lf\n", **x, **y, addition(**x, **y)); break;
case '-':printf("%lf - %lf = %lf\n", **x, **y, subtraction(**x, **y)); break;
case '*':printf("%lf * %lf = %lf\n", **x, **y, multiplication(**x, **y)); break;
case '/':printf("%lf / %lf = %lf\n", **x, **y, division(**x, **y)); break;
default:printf("bad operator!");
}
return 0;
}
void newcalc(char* restart,double* x, char* opp, double* y)
{
while (restart != (char*)'N')
{
readcalc(&x, &opp, &y);
switchfunk(&x, &opp, &y);
printf("New Calc? (Y,N) \n");
fflush(stdin);
scanf("%c", &restart);
if (restart != (char*)'Y'&&restart != (char*)'N')
{
printf("Bad input!");
}
}
}
double readcalc(double** x,char** opp,double** y)
{
printf("\n Type your calculation!(z.B.4+7)\n");
scanf("%lf%c%lf",x,opp,y);
return 0;
}
double addition(double a,double b)
{
double c = 0;
c = a + b;
return c;
}
double subtraction(double a, double b)
{
double c = 0;
c = a - b;
return c;
}
double multiplication(double a, double b)
{
double c = 0;
c = a*b;
return c;
}
double division(double a, double b)
{
double c = 0;
c = a / b;
return c;
}
Best regards!
You have so many problems in your code, most of them related to your use of pointers. Here's one problem:
In the newcalc function you have the following condition in a loop:
restart != (char*)'N'
That will not work as you expect, in fact it will always be true and give you an infinite loop.
The reason is that restart is a pointer which points to the location of the local restart variable in the main function. It will never be the same as (char *) 'N' (which is a pointer pointing to address 78).
How to solve this specific problem? To start with, don't have it as an argument, declare it as a local (non-pointer!) variable:
char restart = 'y';
Then use it normally in the loop condition
while (restart == 'y' || restart == 'Y') { ... }
And to hint to more pointer problems, remember that scanf want a pointer to the variable where to store the value?
But in e.g. the readcalc function the variables x, opp and y are pointers to pointers to where the data should be stored, and yet you pass these pointers-to-pointer to scanf:
scanf("%lf%c%lf",x,opp,y);
Here, you should use pointers as argument to readcalc function, but not pointers-to-pointers.
In other words, it should be declared as
double readcalc(double*,char*,double*);
You most likely have many other problems with your (unnecessary) use of pointers and pointers-to-pointers, but these were the ones that really stood out.
I think you are misusing pointers and using addresses rather than the values themselves. Also, you are using pointers to pointers while you are not in need to do so. Take a look at the following code.
#include <stdio.h>
#include <stdlib.h>
void newcalc (char*,double*,char*,double*);
double switchfunk(double*, char*, double*);
double readcalc(double*,char*,double*);
double addition(double,double);
double subtraction(double,double);
double multiplication(double,double);
double division(double,double);
int main()
{
double a=0, b=0;
char op='R', restart = 'Y';
newcalc(&restart,&a,&op,&b);
fflush(stdin);
getchar();
return 0;
}
double switchfunk (double* x, char* opp, double* y)
{
printf("\n ---CALCULATOR--- \n\n\n");
switch ( *opp )
{
case '+':
printf("%lf + %lf = %lf\n", *x, *y, addition(*x, *y));
break;
case '-':
printf("%lf - %lf = %lf\n", *x, *y, subtraction(*x, *y));
break;
case '*':
printf("%lf * %lf = %lf\n", *x, *y, multiplication(*x, *y));
break;
case '/':
printf("%lf / %lf = %lf\n", *x, *y, division(*x, *y));
break;
default:printf("bad operator!");
}
return 0;
}
void newcalc(char* restart,double* x, char* opp, double* y)
{
while ( *restart == 'Y' || *restart == 'y')
{
readcalc(x, opp, y);
switchfunk(x, opp, y);
printf("New Calc? (Y,N) \n");
fflush(stdin);
scanf("%c", restart);
// if (restart != (char*)'Y'&&restart != (char*)'N')
// {
// printf("Bad input!");
// }
}
}
double readcalc(double* x,char* opp,double* y)
{
printf("\n Type your calculation!(z.B.4+7)\n");
scanf("%lf%c%lf",x,opp,y);
return 0;
}
double addition(double a,double b)
{
return a + b;
}
double subtraction(double a, double b)
{
return a - b;
}
double multiplication(double a, double b)
{
return a*b;
}
double division(double a, double b)
{
return a / b;
}

Resources