complex number calculator in c using functions and structs - c

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);
...

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.

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.

function declaration and call and definition in c

Why is this code not running after printing of array if I take value of n>=9?
#include <stdio.h>
#include <math.h>
float mean_function(float array[],int n);
int main() {
int i,n;
float array[n],mean,sum=0,s2,summation,deno,C[i],elements;
printf("Enter No of Elements\n");
scanf("%d",&n);
printf("Enter Elements\n");
for(i=0;i<n;i++){
scanf("%f",&array[i]);
printf("%f",array[i]);
}
printf("sample variance(s2) : (sum((x-mean)*(x-mean)))/(n-1) /n");
printf("population variance(sigma2) : (sum((x-u)*(x-u))/n");
mean_function(array,n);
for(i=0;i<n;i++) {
deno=((array[i]-mean)*(array[i]-mean));
C[i]=deno;
summation=summation+C[i];
}
s2=((summation)/(n-1));
printf("s2=%f \n",s2);
}
float mean_function(float array[],int n) {
int i;
float sum=0,mean;
for(i=0;i<n;i++){ sum=sum+array[i]; }
mean=(sum/n);
return mean;
}
Why is this code not running after printing of array if I take value
of n>=9?
Some thoughts about your code (and about building programs in steps):
Arrays in C don't change in size once defined. VLAs are out for a variety of reasons. malloc() is in.
Use double, unless there is a specific reason to use floats.
Define and initialize one variable per line. Uninit vars can only result in an error as mentioned by #Jens.
Function declarations at the top (which you have done)
During development, there is no need to complicate things with a scanf (at least initially). It only adds an unwarranted layer of complexity. If you are testing statistical functions (mean, variance), put numbers in a pre-defined static array and verify functionality first.
C[i] as been declared with uninitialized i.
For this initial phase of building this program, I include a basic program.
I am not a fan of zero space between tokens (but ignore that)
Consider calling your array something other than 'array'.
Calculating the size of the samples array allows you to change the number of elements without changing anything else in code; which adds another layer of complexity to an already difficult phase.
#include <stdio.h>
#include <math.h>
double sample_mean(double* p, int n);
int main()
{
double samples[] = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 16.5, 2.3};
double mean = 0.0;
int size_samples = sizeof samples/sizeof(double);
printf("size_samples = %d\n", size_samples);
mean = sample_mean(samples, size_samples);
printf("Mean = %.2lf", mean);
}
// -------------------------------
double sample_mean(double* p, int n)
{
double mean = 0.0;
double total = 0.0;
for(int i = 0; i < n; i++)
total += *p++;
mean = total/n;
return mean;
}
Once this functionality is present (saved), you can start working on other stat functions. This way you can work step by step to get closer to the desired outcome.
Next up you can define sample_variance(double* p, int n) and work on that knowing that additional(new errors) are not coming from your code written so far.
Output:
size_samples = 8
Mean = 5.24
I hope it helps.
The code is likely not running because array[n] is declared with an uninitialized n. At the time you read n with scanf(), the array does not automatically "grow into the right size". You should either declare array big enough, or if you really want it to be user-defined, use malloc to allocate it (read the comp.lang.c FAQ) and all Stackoverflow questions tagged array...)
In addition, the scanf at some point fails. Note that when you enter numbers, you also have the "Enter" as a newline ('\n') in the input stream. You never read the newline so the next scanf fails.
This becomes obvious when you actually check the return value from scanf with code like this:
if (scanf("%f", &array[i]) == 1) {
/* successfully converted 1 item */
}
else {
/* scanf failed */
}
Usually what you want is to skip whitespace in the input. You do this by placing a space in the scanf format. Note that a single space tells scanf to skip any amount of white-space.
if (scanf(" %f", &array[i]) == 1) {

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.

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