complex number calculator: arithmetic operations with struct variables in c - 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.

Related

complex number calculator in c using functions and structs

Kind of a continuation of my last post, I'm trying to write a complex number calculator using structs and functions. My program has to have a function for reading in complex numbers from user input, and it has to have another function for adding them. This is the function prototype I was given:
Complex read_complex(void)
This is the prototype I have to use and it can't be changed. Right now I'm trying trouble passing the values I scan in from the above function into my function for adding the complex numbers. This is my code:
#include <stdio.h>
#include <math.h>
#include<string.h>
typedef struct Complex_ {
double RealPart;
double ImagPart;
} Complex;
Complex read_complex(void);
Complex add_complex(Complex z1, Complex z2);
Complex mul_complex(Complex z1, Complex z2);
int main(void) {
char ent[50];
Complex user1, user2;
printf("Enter Add for addition, Mult for multiplication, MA for magnitude and angle, or Exit to quit: ");
scanf("%s", ent);
if (ent[0] == 'A') {
read_complex();
add_complex(user1, user2);
}
else if (ent[0] == 'M' && ent[1] == 'u') {
read_complex();
mul_complex(user1, user2);
}
else if (ent[0] == 'M' && ent[1] == 'A') {
read_complex();
}
else {
}
return(0);
}
Complex read_complex(void) {
Complex* user1;
Complex* 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;
}
Complex add_complex(Complex z1, Complex z2) {
Complex z3;
z3.RealPart = z1.RealPart + z2.RealPart;
z3.ImagPart = z1.ImagPart + z2.ImagPart;
printf("(%lf + %lfi) + (%lf + %lfi) = %lf + %lfi", z1.RealPart, z1.ImagPart, z2.RealPart, z2.ImagPart, z3.RealPart, z3.ImagPart);;
return(z3);
}
Complex mul_complex(Complex z1, Complex z2) {
Complex z3;
z3.RealPart = z1.RealPart * z2.RealPart;
z3.ImagPart = z1.ImagPart * z2.ImagPart;
return(z3);
}
(Large parts of the code are incomplete right now because I'm just trying to figure out the adding part). The current problem I'm having is that when I run the code, I get an error saying the user1 and user2 variables are uninitialized, and I don't know how to initialize struct variables.
You seem to have a misunderstanding of how pointers work.
The way you've written read_complex, you seem to think that the pointers user1 and user2 in this function automatically refer to the variables of the same name in the main function. That's not how C works.
What you actually have is two uninitialized pointers inside of read_complex that you then attempt to dereference via the -> operator. You're also not returning anything from this function even though it's declared to do so.
This function is supposed to return a single copy of a Complex, so you should create one locally, read the values into it, then return it. The return value should then be assigned to a local variable. So this also means you need to call this function for each Complex you read.
Also, you may want to review how to multiply complex numbers.
This is the function prototype I was given: Complex read_complex(void) This is the prototype I have to use and it can't be changed.
read_complex() returns 1 object of type Complex. Use it to read 1, not 2, complex numbers.
Let use use that function to read and also create another function that calls it to read 2 complex numbers.
// Receive the address of 2 objects,
// so this code knows where to save the result.
void read_complex2(Complex *a, Complex *b) {
printf("Enter first complex number: ");
*a = read_complex();
printf("Enter the second complex number: ");
*b = read_complex();
}
read_complex()
read_complex() becomes simple: read 2 double. Check results.
Complex read_complex(void) {
Complex x;
if (scanf("%lf %lf", &x.RealPart, &x.ImagPart) != 2) {
fprintf(stderr, "Invalid input.\n");
exit(EXIT_FAILURE);
}
return x;
}
main()
Adjust like:
if (ent[0] == 'A') {
//read_complex();
read_complex2(&user1, &user2);// Pass in addresses of objects.
add_complex(user1, user2);
...

Passing a variable by value, printf doesn’t show the correct result

I'm a university student and in one of my exercises to train c programming I got stuck on an error with a print function. I used CLION which was great but now moved on into VS Code, because the teacher say it´s the most used in a professional environment. What are your thoughts on it?!
main.cpp
#include <stdio.h>
#include "complex.h"
int main (){
Complex x;
inputNmbr(x);
printNmbr(x);
return 0;
}
complex.h
#include <stdio.h>
typedef struct{
float r,i;
}Complex;
Complex inputNmbr(Complex x){
printf("Input an imaginary number (R +/- I):\n");
scanf("%f %f", &x.r, &x.i);
return x;
}
void printNmbr (Complex x){
printf("Imaginary number: %.2f +/- %.2f\n", x.r, x.i);
}
Terminal
aluno#aluno-VirtualBox:~/Desktop/Programação por objetos/P1/EX2$ ./main\
Input an imaginary number (R +/- I):
1 2
Imaginary number: 0.00 +/- 0.00
So the printf function always shows 0 0 and I´m not understanding the source of this error.
P.S. After being attacked about the C/C++ tag I´m posting the exercise (the reason why I put the both tags is related to this):
Write a module in C that allows working with complex numbers.
Create the files complex.h and complex.cpp where you should implement the following functionalities:
The definition of data structure (Complex) to represent a complex number
(r, i);
A function that reads a complex number;
A function that writes a complex number in the format: #.#+/-#.#i (where +/- depends on the sign of the imaginary part);
A function for each of the following operations:
Addition: a+bi+c+di=(a+c)+(b+d)i
Subtraction: a+bi-c+di=(a-c)+(b-d)i
Multiplication: (a+bi)*(c+di)=(ac-bd)+(bc+ad)i
Division:
(a+bi) / (c+di)=((ac+bd)/(c^2+d^2))+((bc-ad)/(c^2+d^2))i
I am not going through all your execise, however, the problem of your incorrect printf is that your struct variable x is passed "by value" to the function inputNmbr. This means that when invoking it, a copy of your variable is created and put on the function stack, and even if you modify the value inside the function, the modification is not reflected in the original variable.
A solution can be to change the input parameter of inputNmbr function so to make it a pointer. For example:
void inputNmbr(Complex * x){
printf("Input an imaginary number (R +/- I):\n");
scanf("%f %f", &(x->r), &(x->i));
}
In this case, your main will be:
int main (){
Complex x;
inputNmbr(&x);
printNmbr(x);
return 0;
}
Another method of doing this would be having in main:
Complex x = inputNmbr();
and in your fn definition:
Complex inputNmbr(){
Complex a;
printf("Input an imaginary number (R +/- I):\n");
scanf("%f %f", &a.r, &a.i);
return a;
}
The choice of a "return" vs using pass by address to return is stylistic but may also depend on a standard depending on your professor.

Why does my C program keep giving me 1 as the error?

I ran it, and everything seems to be fine--except that it keeps giving me a margin of error of 1. Why is it doing this?
The program is supposed to prompt the user to input an estimation for the cube root of 3, and it uses Newton's method of approximation to show how many attempts it took to get to the approximation. After 500 attempts or a margin of error less than 0.000001, it's supposed to exit the loop. Why, though, doesn't the margin of error change?
Here's my code:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int main()
{
float a, i, e; //declare float variables
printf("Consider the function f(x) = x^3 - 3 = 0.\n");
printf("Simplifying, we get x^3 = 3.\n");
printf("Simplifying it further, we get x = 3^(1/3).\n");
printf("Enter your estimate of the root: ");
scanf("%f", &a); //prompt user to guestimate
printf("So you're saying that x = %f.\n", a);
i=0; //initiate attempt counter
e=abs((a-pow(3, (1/3)))/pow(3, (1/3))); //margin of error formula
while (e>=0.000001 && i<=500) //initiate while loop with above expressions
{
if (a!=pow(3, (1/3)))
{
printf("Attempt %f: ", i);
a = a - (pow(a, 3) - 3)/(3*pow(a, 2));
printf("%f, ", a);
printf("%f margin of error\n", e);
i=i+1;
}
else
break;
}
}
abs() deals with ints and will return an int, you need fabsf().
In the same way, pow() is for doubles, you should use powf().
Another mistake is writing 1/3 and expecting 0.333... as a result. 1 and 3 are int literals, so the operation performed is integer division. You need to use float literals, such as 1.0f/3.0f.
That's it for type compatibility. I can see another error however : you expect e to somehow remember its formula and reapply it automagically. That's not how imperative languages work : when you write e = something, "something" is calculated and stored in e once and for all. You're doing it correctly for a, now just bring e=abs(...); inside the while loop to update it each time.

can't do multiplication operation on 'double' numbers

I am trying to write some functions for Complex type numbers, but I couldn't make this work.
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
typedef struct{
double a; /* Real*/
double b; /* Imaginary*/
}Complex;
Complex Nmbr1,Nmbr2;
int main()
{
Complex NmbrMulti;
printf("Type the value of the real part of the first number\n");
scanf("%d",&Nmbr1.a);
printf("\nType the value of the Imaginary part of the first number\n");
scanf("%d",&Nmbr1.b);
printf("\nType the value of the real part of the second number\n");
scanf("%d",&Nmbr2.a);
printf("\nType the value of the Imaginary part of the second number\n");
scanf("%d",&Nmbr2.b);
NmbrMulti.a = Nmbr1.a * Nmbr2.a - Nmbr1.b * Nmbr2.b ;
NmbrMulti.b = Nmbr1.a * Nmbr2.b + Nmbr2.a * Nmbr1.b ;
printf("\nThe Multiplication : %d+i", NmbrMulti.a);
printf("%d\n", NmbrMulti.b);
return 0;
}
but I get the result 0+i0 , it seems that the problem is with the operations, is there another way to do multiplication for double numbers that I'm not aware of ?
When scanf sees %d, the corresponding argument must be a pointer to int. If the argument is a pointer to double, the code should be %lf.
Reference
http://www.cplusplus.com/reference/cstdio/scanf/
Formatting for double in C is lf rather than d. The latter implies and int.

C if-statement issues?

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.

Resources