C if-statement issues? - c

I'm trying to practice making if-statements and am having very little luck with this. Right now I'm trying to make a trigonometric calculator, a very simple one, using if statements, but I can't get it working. The actual problem occurs after input the trig function (sine, cosine, tangent). This is what happens.
1. I compile it
2. It outputs the user prompt
3. I input the function and hit enter
4. The program jumps to a new blank line
5. Nothing happens and the program closes if I press enter
Here is the code itself. Please be kind if I've done something monumentally stupid, I'm pretty new to C.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int main(void)
{
float x;
float a, o, h;
float sine, cosine, tangent;
printf("Enter the trig function you wish to calculate: ");
scanf("%f", &x);
if (x == sine)
{ printf("Enter the value of the opposite leg: ");
scanf("%f", &o);
printf("Enter the value of the hypotenuse: ");
scanf("%f", &h);
sine = o / h;
printf("The sine is equal to %f", sine);
}
if (x == cosine)
{ printf("Enter the value of the adjacent leg: ");
scanf("%f", &a);
printf("Enter the value of the hypotenuse: ");
scanf("%f", &h);
cosine = a / h;
printf("The cosine is equal to %f", cosine);
}
if (x == tangent)
{ printf("Enter the value of the opposite leg: ");
scanf("%f", &o);
printf("Enter the value of the adjacent leg: ");
scanf("%f", &a);
tangent = o / a;
printf("The tangent is equal to %f", tangent);
}
getch();
}
Thank you to everyone who who was actually helpful and wasn't rude about my lack of understanding, I didn't realize I had to add a numerical character instead of just a character.

Simple (minimal) fixes
Yes, you're on the verge of doing various things that an experienced programmer would call silly, but they're the sorts of mistakes that novices make (you're neither the first nor the last to make them).
int main(void)
{
float x;
float a, o, h;
float sine, cosine, tangent;
printf("Enter the trig function you wish to calculate: ");
scanf("%f", &x);
if (x == sine)
The primary problem is that you've not given sine, cosine or tangent values, so you've no idea what to enter to make the equality work.
The secondary problem is that comparing floating point numbers for equality is not a good idea.
You'd probably do best with something like:
int main(void)
{
int x;
float a, o, h;
enum { sine, cosine, tangent };
printf("Enter the trig function (0 = sine, 1 = cosine, 2 = tangent): ");
scanf("%d", &x);
if (x == sine)
This is more or less orthodox, and reading and comparing integers for equality is reliable. You would have to change the actions since I've pre-empted the names sine, cosine, and tangent as enumeration (integer) constants. You could work around that by using upper-case names for the constants (that's pretty orthodox), or using a prefix for the names, or ...
int main(void)
{
int x;
float a, o, h;
float sine, cosine, tangent;
enum { SINE, COSINE, TANGENT };
printf("Enter the trig function (0 = sine, 1 = cosine, 2 = tangent): ");
scanf("%d", &x);
if (x == SINE)
Friendlier input
As you might gather from the comments below, it would be better to allow the user to enter the name of the function they'd like to enter instead of making them enter a coded number. That's a little trickier to code up reliably, which is the main reason why I left the answer above using numbers.
#include <stdio.h>
#include <string.h>
int main(void)
{
char line[4096];
printf("Enter trig function you wish to calculate: ");
if (fgets(line, sizeof(line), stdin) != 0)
{
char *nl = strchr(line, '\n');
if (nl != 0)
*nl = '\0';
if (strcmp(line, "sine") == 0)
{
/* Process sine */
}
else if (strcmp(line, "cosine") == 0)
{
/* Process cosine */
}
else if (strcmp(line, "tangent") == 0)
{
/* Process tangent */
}
else
{
fprintf(stderr, "Unrecognized trig function (%s)\n", line);
}
}
}
The 4096 is simply a big round number that's so long that it is very unlikely that anyone will ever enter a line that is longer than that. If they do enter such a line, then GIGO and they get what they deserve (which will be a polite error message that the name they entered was not recognized).
This is still not wonderful code. It might be reasonable to strip leading and trailing white space, and maybe case-convert the input to lower case, and one of the messages should probably identify the valid function names. It would be possible to have the code loop repeatedly, but then you'd need a function to prompt and read the response, etc. All of which adds usability at the expense of more code which complicates things unnecessarily for a beginning programmer.

Your if statements aren't working because you're comparing the input value, x, with a floating point value that hasn't been set. I think what you want to do is this:
int x;
printf("Enter the trig function you wish to calculate\n");
printf("1=sine, 2=cosine, 3=tangent: ");
scanf("%d", &x);
if (x == 1)
{
// do sine
}
else if (x == 2)
{
// do cosine
}
else if (x == 3)
{
// do tangent
}
else
{
printf("I don't know that function.\n");
}
Monumentally stupid? Naw. It's an easy kind of mistake to make when you first start programming. Stick with it. We've all been there.

I'm not sure what you are entering into the program to begin with, but this is where your error is. If you are entering a character array (a "string"), and that is being passed to x, you can't compare that with a floating point value. Also, your sine, cosine, and tangent variables have no value/have not been assigned anything. To solve your issue, assign your variables a number, such as float sine = 1; and make sure what you enter into the command line to pass to x is a number. If you want to enter "cosine", and pass that value to x, then you will have to change your x variable to a char array, such as char[] x = "", and then change your sine, cosine, and tangent variables to be character arrays as well. If you do change your variables to arrays, remember to remove the & from the scanf statement, like this -> scanf("%s", x);.

Right now, this code:
float x;
float a, o, h;
float sine, cosine, tangent;
printf("Enter the trig function you wish to calculate: ");
scanf("%f", &x);
if(x == sine)
...reads a value into x, but then compares it to the current value of sine. Unfortunately, you haven't initialized sine, so it's comparing to some unknown, semi-random value.
When you compare to cosine and tangent, you're doing more of the same.
None of these comparisons has a meaningful result (e.g., they might easily all be true).
At a guess, you probably want to have the user enter a string, and compare that to the values "sine", "cosine", and "tangent", using strcmp.

Related

complex number calculator: arithmetic operations with struct variables in c

Trying to write a c program that can do complex number calculations. The program has to use this structure:
typedef struct Complex_ {
double RealPart;
double ImagPart;
} Complex;
It has to use one function to read in user inputs for the complex numbers, and another function to add them, another to multiply them, etc. I'm trying to get the function to add the numbers right now, and I'm trying to figure out how to do this.This is the function for reading in the user input:
Complex read_complex(void) {
Complex user1, user2;
printf("Enter first complex number: ");
scanf("%lf %lf", &user1.RealPart, &user1.ImagPart);
printf("Enter the second complex number: ");
scanf("%lf %lf", &user2.RealPart, &user2.ImagPart);
return;
}
And this is what I have so far for adding the complex numbers:
Complex add_complex(Complex z1, Complex z2) {
Complex z3;
z3 = z1 + z2;//error on this line
return(z3);
}
The function has to return z3, and z3 needs to equal z1 + z2, and z1 and z2 have to be variables of type Complex. I'm not sure how to make it work with these specifications since you can't do arithmetic operations with struct variables.
You can't add or substract the data structures.
Complex add_complex(Complex z1, Complex z2) {
Complex z3;
z3.RealPart = z1.RealPart + z2.RealPart;
z3.ImagPart = z1.ImagPart + z2.ImagPart;
return(z3);
}
Not what you're asking about, but your read_complex function as shown won't work. Suggest changing to something like the following
#include <stdbool.h>
bool read_complex(Complex* user1, Complex* user2)
{
bool inputValid = false;
// weak check for validity, a non-NULL pointer isn't necessarily
// valid. In fact, probably better to skip this check and instead
// document/accept UB if user1 and/or user2 are not valid pointers.
if (user1 != NULL && user2 != NULL)
{
printf("Enter first complex number: ");
if (scanf("%lf %lf", &(user1->RealPart), &(user1->ImagPart)) == 2)
{
printf("Enter the second complex number: ");
if (scanf("%lf %lf", &(user2->RealPart), &(user2->ImagPart)) == 2)
{
inputValid = true;
} // else, print error message?
} // else, print error message?
}
return inputValid;
}
scanf returns an int indicating the number of inputs that matched the supplied format specifiers. That should be 2 for each input, if not, you know there's a problem. The caller of read_complex can decide what to do next if it returns false.

Example of a colloquium exam

Check the image
This is my 1st post so have that in mind while reading my question.
I have an exam of a colloquium but my code does not provide me the correct result.
So if anyone could help me that would be great. :)
These are the informations that are provided in the exam:
A function y=f(x)=ax^2+bx+c
We have to find the surface that is below the chart but keep in mind that dx(Delta X)=B-A and the height goes like this: A,A+dx,A+2dx, .... , B-dx.
As dx value gets lower the surface will be more accurate.
You have to write the program so that the surface with precision 0.001
This is my code so could someone who is good in C check it please.
Thank you.
#include <stdio.h>
#include <math.h>
int main()
{
int a,b,c;
double A,B,dx,p,D,q,x,y,nv,nv1,nv2,sv;
do{
printf("Insert a & b: "),scanf("%lf %lf",&A,&B);
} while(A<1 || B<1);
nv=dx=B-A;
do{
printf("enter odds: "),scanf("%d %d %d",&a,&b,&c);
p=(-b)/2;
D=sqrt(pow(b,2)-4*a*c);
q= -D/4*a;
} while( a<0 || p<0 || q<0);
do{
sv=nv;
dx/=2;
nv=0;
for(x=A;x<p;x+=dx)
for(dx=B-A;dx<q;dx/=2)
nv1+=x*dx;
for(y=p;y<=B;y+=dx)
for(dx=q;dx<B;dx/=2)
nv2+=y*dx;
nv=nv1+nv2;
}while(fabs(nv-sv)>0.001);
printf("The surface is %lf",nv);
return 0;
}
You want to find the approximation of a definite integral of a quadratic function. There are several issues with your code:
What is the restriction of A ≥ 1 and B ≥ 1 for? A parabola is defined over the whole abscissa. If anything, you should enforce that the input is numeric and that two values were given.
You don't need to find the vertex of the parabola. Your task is to create small rectangles based on the left x value of each interval as the image shows. Therefore, you don't need p and q. And you shouldn't enforce that the vertex is in the first quadrant on the input without indication.
Why are the coefficients of the parabola integers? Make them doubles to be consistent.
Because you don't need to know the vertex, you don't need to split your loop in two. In your code, you don't even check that p is between A and B, which is a requirement of cour code.
What is the inner loop for? You are supposed to just calculate the area of the current rectangle here. What's worse: you re-use the variable dx as iteration variable, which means you lose it as an indicator of how large your current interval is.
The repeated incrementing of dx may lead to an accumulated floating-point error when the number of intervals is large. A common technique to avoid this is to use an integer variable for loop control and the determine the actual floating-point variable by multiplication.
The absolute value as a convergence criterion may lead to problems with small and big numbers. The iteration ends too early for small values and it may never reach the criterion for big numbers, where a difference of 0.001 cannot be resolved.
Here's a version of your code that puts all that into practice:
#include <stdio.h>
#include <math.h>
int main()
{
double a, b, c;
double A, B;
printf("Lower and upper limit A, B: ");
scanf("%lf %lf", &A, &B);
printf("enter coefficients a, b, c: ");
scanf("%lf %lf %lf", &a, &b, &c);
double nv = 0;
double sv;
int n = 1;
do {
int i;
double dx;
sv = nv;
n *= 2;
dx = (B - A) / n;
nv = 0;
for (i = 0; i < n; i++) {
double x = A + i * (B - A) / n;
double y = a*x*x + b*x + c;
nv += dx * y;
}
} while(fabs(nv - sv) > 0.0005 * fabs(nv + sv));
printf("Surface: %lf\n", nv);
return 0;
}
The code is well-behaved for empty intervals (where A = B) or reversed intervals (where A > B). The inpt is still quick and dirty. It should really heck that the entered values are valid numbers. There's no need to restrict the input arbitrarily, though.

Programming C calling function area of circle and rectangle

#include <stdio.h>
#define PI 3.14159
int Circle (int);
int Rectangle (int, int);
int main()
{
int a;
int b;
int c;
int d;
int area;
int AreaOfCircle;
int AreaOfRectangle;
int area1;
printf("Program to calculate area\n");
printf("1 - Circle\n");
printf("2 - Rectangle\n");
printf("\n");
printf("What option = \n");
scanf("%d", &a);
if(a=1)
{
area=Circle(b);
printf("Area= %d\n", area);
}
else if(a=2)
{
area1=Rectangle(c,d);
printf("Area= %d\n", area1);
}
return 0;
}
int Circle (int b)
{
int area;
printf("radius= \n");
scanf("%d", &b);
area=PI*b*b;
return area;
}
int Rectangle(int c, int d)
{
int area1;
printf("length= \n");
scanf("%d",&c);
printf("width= \n");
scanf("%d",&d);
area1=c*d;
return area1;
}
//I want to ask if my coding is ok .. but as I run it the output only ask for radius which is the calling function for circle .. but if i want to call rectangle the output also shows calculation for circle .. can someone help me to spot the mistake .. by the way this is my first coding about calling function and I just started learning coding c last month .. T-T
With C you use == to evaluate (e.g. if (x == 1)). "=" is assignment, so you'll always hit the first block.
Also, you're accepting parameters which you're then modifying, which is not good practice. Consider declaring your variables at usage time also, the "everything at the top of the block" paradigm is very dated.
This question is not about functional programming, this is an example of imperative programming.
Also, your input being poured directly into an integer is not bounds checked, consider a switch/case so you can add a default of "invalid input" and extend to different shapes in the future.
Yes bro just make if(a==1) and else if(a==1).
You've used the assignment = operator instead of the comparison == operator.
A statement like
if(a=1)
will assign a value of 1 to a and check then check for the non-zero value of a [which always evaluates to TRUE].
Instead, what you want is
if (a == 1)
which evaluates to TRUE if a contains 1. Same for other comparison(s) also.
Note: In your int Circle (int b) case you're storing the result to an int, which will truncate the result of a double/float multiplication. To get the exact value, make the area as float or double and use %f/ %lf format specifier.
Next, as per the logical part, you don't need to pass b, c, d as parameters to the called functions. Simply a local variable in the functions would do the job.

Finding if two triangle are congruent

The problem goes like this:
Write a program that reads the three angles and sides of two triangles and print if they are congruent or not. We do not how many times the user wants to do it.
#include <stdio.h>
#include <conio.h>
int main()
{
float l1,l2,l3,l4,l5,l6;
float a1,a2,a3,a4,a5,a6;
char ans;
int d=1;
while(d<=2)
{
printf("\nIntroduce the sides of triangle %d:",d);
scanf("%f %f %f",&l1,&l2,&l3);
printf("Introduce the angles of triangle %d:",d);
scanf("%f %f %f",&a1,&a2,&a3);
{
if(l1==l4 &&l2==l5 && l3==l6 && a1==a4 && a2==a5 && a3==a6)
printf("\n\tCongruent");
else
printf("\n\tNot congruent");
}
}
getch();
return 0;
}
That's my code but there is a problem in the beggining, because i soon as it ends the angles prompt, the program just finishes and says they are not congruent, without ever asking for triangle number 2, therefore i havent done the "asking is the user wants to do other triangles thing". I know that my code is somewhat wrong, but i dont get where.
All help is appreciatead!
This is because your loop is incomplete. Instead of while(d<=2), I recommend for (int d = 1; d <= 2; ++d).
Is it a requirement that the user enter the vertices of both triangles in the same sequence? If not, then you would need to check WHICH angles match, then check the corresponding sides. Also, is in necessary to validate that the given angles and sides form a valid triangle? This could potentially become a very complicated problem.
You are comparing the sides before you read the data from both triangles. The comparison must be outside the while.
You need to increment d somewhere (anywhere) inside the loop.
You dont need those { } closing the if-else.
You are not checking if the values are acceptable, so let's suppose whoever use this program will only provide correct value, so...
The easiest way to check for congruency would be to check if all the sides on the first triangle has a correspondent side on the second triangle.
The way to do the comparison I'll leave to you as a challenge... You can start as:
if(l1 == l4 && l2 == l5 && l3 == l6) ...
Think how you would solve that in a papper or something, once you have an idea on how to solve, try and implement it. =)
I went and changed and added some things, and now it looks like this:
#include <stdio.h>
#include <conio.h>
int main()
{
float l1,l2,l3,l4,l5,l6;
float a1,a2,a3,a4,a5,a6;
char resp;
printf("\n\t Triangles");
printf("\nBegin?");
while(resp=getchar()=='y')
{
fflush(stdin);
printf("\nIntroduce the sides of the first triangle:");
scanf("%f %f %f",&l1,&l2,&l3);
printf("Introduce the angles of first triangle:");
scanf("%f %f %f",&a1,&a2,&a3);
printf("\nIntroduce the sides of the second triangle:");
scanf("%f %f %f",&l4,&l5,&l6);
printf("Introduce the angles of the second triangle:");
scanf("%f %f %f",&a4,&a5,&a6);
fflush(stdin);
if((l1==l4|| l1==l5 ||l1==l6) && (l2==l4 ||l2==l5 || l2==l6) && (l3==l4 || l3==l5 || l3==l6))
printf("\n\tCongruent");
else
printf("\n\tNot congruent");
printf("\nMore triangles?:");
}
getch();
return 0;
}
It runs pretty good , does everything fine but i was wondering is there any way to do the problem without asking for printf("\nBegin?");, or asking for it is the only way to do it?
If there is another way , do that means that i will have to change mywhile(resp=getchar()=='y')?

I can't get this (simple) loop to work properly

I'm in a programming class right now, and was asked to create a program that calculated the sum of a user's input for multiple numbers--then calculate the nth root of the sum. If the number they input was less than 0, the loop is supposed to discard the less than 0 number, then ask again.
Unfortunately, no matter what number I input--it displays "Value needs to be greater than zero!" I tried putting a fflush(stdin); statement in the loop, but that didn't seem to do anything.
Here is my code. I really appreciate any and all help.
#include "stdafx.h"
#include <stdio.h>
#include <math.h>
int main() {
int mTotalNums, mNth; //amount of numbers in set
float mProd = 1, x, mNroot;
printf("How many numbers are in the set?\n");
scanf("%i", &mTotalNums);
mNth = mTotalNums; //set the value of mTotalNums equal to mNth becuase we'll lose the original value of mTotalNums after the loop
while (mTotalNums > 0) {
printf("Input number: ");
scanf("%lf", &x);
if (x > 0) {
mProd *= x;
} else
printf("\nValue needs to be greater than zero!\n");
}
mNroot = pow(mProd, (1 / mNth));
printf("\nThe nth root of the product of %i terms is: %.2f\n", mNth, mNroot);
return 0;
}
"%lf" is the scanf format for a double, but x is declared as float.
To scan a float, you have to use the %f format.
Note also that mTotalNums is not decremented in the loop, so that it will never
terminate.
Read the documentation of scanf(3). Since x is declared as a float, use %f as the scanf format control string. Also, take into account the result of scanf (it would be 1 if successfully read one item).
You should enable all warnings and debug info in your compiler, then learn how to use the debugger (notably to run your program step by step, display local variables, etc....).
(On Linux, if compiling with gcc -Wall -g you would get a useful warning, and the gdb debugger would be helpful...)
Try these modifications to your program (added comments with changes made)
#include "stdafx.h"
#include <stdio.h>
#include <math.h>
int main() {
//amount of numbers in set
int mTotalNums, mNth;
// Change to double for added precision
double mProd = 1.0, x, mNroot;
printf("How many numbers are in the set?\n");
scanf("%i", &mTotalNums);
// Set the value of mTotalNums equal to mNth becuase
// we'll lose the original value of mTotalNums after the loop
mNth = mTotalNums;
// Don't forget to decrement the loop counter
while (mTotalNums-- > 0) {
printf("Input number: ");
scanf("%lf", &x);
if (x > 0) {
mProd *= x;
} else {
printf("\nValue needs to be greater than zero!\n");
}
}
// Change to 1.0 to force compiler to treat as a double
mNroot = pow(mProd, (1.0 / mNth));
printf("\nThe nth root of the product of %i terms is: %.2f\n", mNth, mNroot);
return 0;
}
You mention "calculate the nth root of the sum", but your loop is clearly tallying the cumulative product. To change it to calculate the sum, try the following additions:
// Declare a sum variable
double sum = 0;
// Sum inside your while loop
sum += x;
// Calculate the nth root of the sum instead
mNroot = pow(sum, (1.0 / mNth));
Add printf commands to see what your variables contain before you check them in your logic statements.
You also need to do something to increment/decrement your variable for your while loop... currently nothing is changing mTotalNums, so it will be an infinite loop.
while (mTotalNums > 0) {
printf("Input number: ");
scanf("%lf", &x);
printf("x=%d", x);
if (x > 0) {
mProd *= x;
} else
printf("\nValue needs to be greater than zero!\n");
mTotalNums--;
}

Resources