Jump to content

Multiple Questions, Stuck Here

TukangUsapEmenq
Go to solution Solved by Unimportant,
15 hours ago, dhannemon13 said:

<snip>

First, research how the compilation and linking process works. Once you've done that you can put yourself in the compiler's shoes. Each source file is compiled separately. So when main.c is compiled, it includes complex.h and the function prototypes therein. At no point in time will the compiler see the contents of complex.c while it's compiling main.c. Thus, you should define struct `complex` in the header file complex.h, so the compiler can see it when it's compiling main.c. There is also no need for the `input` char array to be in the struct.

 

Furthermore, what is this doing in complex.h ?

mag(complex a);
phase(complex a);

First of all, they don't have a return type, your compiler should warn for that. In modern C, the canonical way to write things is to explicitly write `void` as a return type when a function returns nothing. In this case, there are no functions `mag` and `phase` in complex.c so remove these prototypes to non-existing functions.

 

Then, in complex.c:

struct complex a,b,c;

When you've typedef'd the struct there's no need for the struct keyword. These global variables are also never used and should be removed.

 

complex getcomplex(char *input){
    
    char input[20];
    complex a,b;

    scanf("%s",&input);
	sscanf(input, "%lf+%lf", &real, &img);

}

The function `getcomplex` takes a string (pointer to char) as argument, presumably the string to be parsed? Why do you declare a new array, also called input and read user input with scanf? Also, there's only a single complex number to be parsed, so no need for a `a` and a  `b`. You should explicitly point sscanf to the struct members. And you have to actually return the parsed complex.

 

complex sum(double real, double img){
   
    complex c;
   
    c.real = a.real + b.real;
    c.img = a.img + b.img;

    printf("Hasil operasi penjumlahan bilangan kompleks = %d + %di", c.real, c.img);
    return (c);

}

This function is supposed to sum 2 complex numbers `a` and `b`. Why does it take 2 doubles `real` and `im` as arguments?

The printf specifier to print doubles is `%lf`, not `%d`.

 

Similar problems plague the other functions in complex.c

 

In main.c

    char ch,p,q,r;

    p = argv[1];
    q = argv[2];
    r = argv[3];

`argv` is a array of pointers to char, not char.

 

   switch(ch){

case 'sum':
    sum(getcomplex(q),getcomplex(r));
    break;

case 'substract':
    substract(getcomplexA(q),getcomplexB(r));
    break;

case 'multiply':
    multiply(getcomplexA(q),getcomplexB(r));
    break;

case 'divide':
    divide(getcomplexA(q),getcomplexB(r));
    break;

    }

You cannot switch on an entire string. Comparing strings has to be done with a function like `strcmp`. Also, strings require double quotes.

 

Final modified program, complex.h:

#ifndef COMPLEX_H_INCLUDED
#define COMPLEX_H_INCLUDED

typedef struct
{
    double real;
    double img;
} complex;

complex getcomplex(const char *input);
complex sum(complex a, complex b);
complex subtract(complex a, complex b);
complex multiply(complex a, complex b);

#endif // COMPLEX_H_INCLUDED

complex.c:

#include <stdio.h>
#include "complex.h"

complex getcomplex(const char *input)
{
    complex a;
    sscanf(input, "%lf+%lf", &a.real, &a.img);
    return a;
}


complex sum(complex a, complex b)
{
    complex c;
   
    c.real = a.real + b.real;
    c.img = a.img + b.img;

    printf("Hasil operasi penjumlahan bilangan kompleks = %lf + %lfi\n", c.real, c.img);
    return c;
}

complex subtract(complex a, complex b)
{
    complex c;

    c.real = a.real - b.real;
    c.img = a.img - b.img;

    printf("Hasil operasi pengurangan bilangan kompleks = %lf - %lfi\n", c.real, c.img);
    return c;
}

complex multiply(complex a, complex b)
{
    complex c;

    c.real = a.real*b.real - a.img*b.img;
    c.img = a.img*b.real + a.real*b.img;

    printf("Hasil operasi perkalian bilangan kompleks = %lf + %lfi\n", c.real, c.img);
    return c;
}

main.c:

#include <stdio.h>
#include <string.h>
#include "complex.h"

int main(int argc, char *argv[])
{

    if (argc < 4 || argc > 5)
    {
    	printf("Tolong masukan minimal 4 argumen. //ex. namafile arg1 arg2\n");
    	return 0;
    }

    const char operator = argv[1][0];
    const char* q = argv[2];
    const char* r = argv[3];

    switch(operator)
    {
        case '+':
        sum(getcomplex(q),getcomplex(r));
        break;

        case '-':
        subtract(getcomplex(q),getcomplex(r));
        break;

        case 'x':
        multiply(getcomplex(q),getcomplex(r));
        break;
    }
}

The `divide` function was removed and implementing it is left as an exercise.

Example command line:

./test_complex + 5+3i 7+2i

output:

Hasil operasi penjumlahan bilangan kompleks = 12.000000 + 5.000000i

 

Hi there, currently struggling with C programming with command line arguments, header file, and how can I call them here. To be honest, still gets a lot confused for even the code that I write.

I've got some progress already, here:

 

(some in Indonesians, but should not be a problem since it's only the output texts.)

 

complex.h header file

#ifndef COMPLEX_H_INCLUDED
#define COMPLEX_H_INCLUDED

complex getcomplex(char *input);
mag(complex a);
phase(complex a);
complex sum(complex a, complex b);
complex substract(complex a, complex b);
complex multiply(complex a, complex b);
complex divide(complex num, complex denum);


#endif // COMPLEX_H_INCLUDED

 

complex.c (still incomplete though, I struggled to how can I extract the real and imaginary numbers out of a string when using command line arguments, so I can do the operations.)

#include <stdio.h>
#include <complex.h>
#include "complex.h"

typedef struct complex
{
    double real;
    double img;
    char input[20];
} complex;

struct complex a,b,c;

complex getcomplex(char *input){
    
    char input[20];
    complex a,b;

    scanf("%s",&input);
	sscanf(input, "%lf+%lf", &real, &img);

}


complex sum(double real, double img){
   
    complex c;
   
    c.real = a.real + b.real;
    c.img = a.img + b.img;

    printf("Hasil operasi penjumlahan bilangan kompleks = %d + %di", c.real, c.img);
    return (c);

}

complex substract(double real, double img){
    
    complex c;

    c.real = a.real - b.real;
    c.img = a.img - b.img;

    printf("Hasil operasi pengurangan bilangan kompleks = %d - %di", c.real, c.img);
    return (c);

}

complex multiply(double real, double img){
   
    complex c;

    c.real = a.real*b.real - a.img*b.img;
    c.img = a.img*b.real + a.real*b.img;

    printf("Hasil operasi perkalian bilangan kompleks = %d + %di", c.real, c.img);
    return (c);

}

complex divide(double real, double img){
   
    complex c;

   
    x = a.real*b.real + a.img*b.img;
    y = a.img*b.real - a.real*b.img;
    z = b.real*b.real + b.img*b.img;

    printf("Hasil operasi pembagian bilangan kompleks = %d + %di", c.real, c.img);
    return 0;
}

For getcomplex() tho, I've got it from my previous topic in this forum, here. It works when I'm separately compile the extract program on another file, but I'm confused how to implement to the program here. With struct, and pointers, but to be honest I'm still confused with pointers.

 

main.c

#include <stdio.h>
#include <string.h>
#include "complex.h"

int main(int argc, char *argv[])
{

    if (argc < 4 || argc > 5)
    {
    printf("Tolong masukan minimal 4 argumen. //ex. namafile arg1 arg2");
    return 0;
    }

    char ch,p,q,r;

    p = argv[1];
    q = argv[2];
    r = argv[3];

    switch(ch){

case 'sum':
    sum(getcomplex(q),getcomplex(r));
    break;

case 'substract':
    substract(getcomplexA(q),getcomplexB(r));
    break;

case 'multiply':
    multiply(getcomplexA(q),getcomplexB(r));
    break;

case 'divide':
    divide(getcomplexA(q),getcomplexB(r));
    break;

    }

}

I can somewhat get the main.c albeit working for the 'if' statements. But not on the case one (or did I actually using the wrong one?)

 

In case you're wondering, the job is make a complex number operations program that using command line arguments.

For example, I'm running command prompt from the program folder, then input "main.exe add 3+1i 2+3i" to the command prompt so the output can be the result of the sum of the complex number.

 

Needs your guys help and references, quick reply will be very appreciated, I'm already stuck at this for be like a day.

Humor me, as you should do.

 

Daily drivers, below.

 

Diccbudd PC

Intel Xeon E3-1225 v2 || ASRock B75M Motherboard || MSI GeForce GTX 1650 Gaming X 4G || Hynix 2x8 GB DDR3 1600 MHz RAM || 480 GB Pioneer APS-SL3 SATA SSD // 1 TB Seagate 2.5" HDD || be quiet! System Power 9 500 W PSU || Cooler Master T20 CPU Cooler || Samsung S19D300 Monitor || Fantech X6 Knight Mouse || VortexSeries VX7 Pro Keyboard

 

Samsung Galaxy A34 5G

8GB RAM, 256GB Internal Storage, 128GB SanDisk Extreme, and you could find the rest of the specs on the interwebz lol

 

Lenovo ThinkPad L390 Yoga

Intel Core i5-8365U || 8 + 16 GB DDR4 (don't ask, gf bought me the 16 GB RAM as my birthday present lol) || Samsung 256GB SSD

 

Personal Server: CasaOS, Home Assistant, ESPHome, Jellyfin.

AMD E-350 || 3GB DDR3 || 120GB random SSD || 1TB Toshiba HDD

 

Audio

Redmi TV Soundbar || KZ EDX Ultra + KZ APTX Bluetooth Module || JCALLY JM6 CX31933 DAC

Link to comment
Share on other sites

Link to post
Share on other sites

You variable "ch" is undefined. and ch is a char type and not an array so it will never equal "sum" since it's only 1 character

Link to comment
Share on other sites

Link to post
Share on other sites

15 hours ago, dhannemon13 said:

<snip>

First, research how the compilation and linking process works. Once you've done that you can put yourself in the compiler's shoes. Each source file is compiled separately. So when main.c is compiled, it includes complex.h and the function prototypes therein. At no point in time will the compiler see the contents of complex.c while it's compiling main.c. Thus, you should define struct `complex` in the header file complex.h, so the compiler can see it when it's compiling main.c. There is also no need for the `input` char array to be in the struct.

 

Furthermore, what is this doing in complex.h ?

mag(complex a);
phase(complex a);

First of all, they don't have a return type, your compiler should warn for that. In modern C, the canonical way to write things is to explicitly write `void` as a return type when a function returns nothing. In this case, there are no functions `mag` and `phase` in complex.c so remove these prototypes to non-existing functions.

 

Then, in complex.c:

struct complex a,b,c;

When you've typedef'd the struct there's no need for the struct keyword. These global variables are also never used and should be removed.

 

complex getcomplex(char *input){
    
    char input[20];
    complex a,b;

    scanf("%s",&input);
	sscanf(input, "%lf+%lf", &real, &img);

}

The function `getcomplex` takes a string (pointer to char) as argument, presumably the string to be parsed? Why do you declare a new array, also called input and read user input with scanf? Also, there's only a single complex number to be parsed, so no need for a `a` and a  `b`. You should explicitly point sscanf to the struct members. And you have to actually return the parsed complex.

 

complex sum(double real, double img){
   
    complex c;
   
    c.real = a.real + b.real;
    c.img = a.img + b.img;

    printf("Hasil operasi penjumlahan bilangan kompleks = %d + %di", c.real, c.img);
    return (c);

}

This function is supposed to sum 2 complex numbers `a` and `b`. Why does it take 2 doubles `real` and `im` as arguments?

The printf specifier to print doubles is `%lf`, not `%d`.

 

Similar problems plague the other functions in complex.c

 

In main.c

    char ch,p,q,r;

    p = argv[1];
    q = argv[2];
    r = argv[3];

`argv` is a array of pointers to char, not char.

 

   switch(ch){

case 'sum':
    sum(getcomplex(q),getcomplex(r));
    break;

case 'substract':
    substract(getcomplexA(q),getcomplexB(r));
    break;

case 'multiply':
    multiply(getcomplexA(q),getcomplexB(r));
    break;

case 'divide':
    divide(getcomplexA(q),getcomplexB(r));
    break;

    }

You cannot switch on an entire string. Comparing strings has to be done with a function like `strcmp`. Also, strings require double quotes.

 

Final modified program, complex.h:

#ifndef COMPLEX_H_INCLUDED
#define COMPLEX_H_INCLUDED

typedef struct
{
    double real;
    double img;
} complex;

complex getcomplex(const char *input);
complex sum(complex a, complex b);
complex subtract(complex a, complex b);
complex multiply(complex a, complex b);

#endif // COMPLEX_H_INCLUDED

complex.c:

#include <stdio.h>
#include "complex.h"

complex getcomplex(const char *input)
{
    complex a;
    sscanf(input, "%lf+%lf", &a.real, &a.img);
    return a;
}


complex sum(complex a, complex b)
{
    complex c;
   
    c.real = a.real + b.real;
    c.img = a.img + b.img;

    printf("Hasil operasi penjumlahan bilangan kompleks = %lf + %lfi\n", c.real, c.img);
    return c;
}

complex subtract(complex a, complex b)
{
    complex c;

    c.real = a.real - b.real;
    c.img = a.img - b.img;

    printf("Hasil operasi pengurangan bilangan kompleks = %lf - %lfi\n", c.real, c.img);
    return c;
}

complex multiply(complex a, complex b)
{
    complex c;

    c.real = a.real*b.real - a.img*b.img;
    c.img = a.img*b.real + a.real*b.img;

    printf("Hasil operasi perkalian bilangan kompleks = %lf + %lfi\n", c.real, c.img);
    return c;
}

main.c:

#include <stdio.h>
#include <string.h>
#include "complex.h"

int main(int argc, char *argv[])
{

    if (argc < 4 || argc > 5)
    {
    	printf("Tolong masukan minimal 4 argumen. //ex. namafile arg1 arg2\n");
    	return 0;
    }

    const char operator = argv[1][0];
    const char* q = argv[2];
    const char* r = argv[3];

    switch(operator)
    {
        case '+':
        sum(getcomplex(q),getcomplex(r));
        break;

        case '-':
        subtract(getcomplex(q),getcomplex(r));
        break;

        case 'x':
        multiply(getcomplex(q),getcomplex(r));
        break;
    }
}

The `divide` function was removed and implementing it is left as an exercise.

Example command line:

./test_complex + 5+3i 7+2i

output:

Hasil operasi penjumlahan bilangan kompleks = 12.000000 + 5.000000i

 

Link to comment
Share on other sites

Link to post
Share on other sites

12 hours ago, Unimportant said:

First, research how the compilation and linking process works. Once you've done that you can put yourself in the compiler's shoes. Each source file is compiled separately. So when main.c is compiled, it includes complex.h and the function prototypes therein. At no point in time will the compiler see the contents of complex.c while it's compiling main.c. Thus, you should define struct `complex` in the header file complex.h, so the compiler can see it when it's compiling main.c. There is also no need for the `input` char array to be in the struct.

 

Furthermore, what is this doing in complex.h ?


mag(complex a);
phase(complex a);

First of all, they don't have a return type, your compiler should warn for that. In modern C, the canonical way to write things is to explicitly write `void` as a return type when a function returns nothing. In this case, there are no functions `mag` and `phase` in complex.c so remove these prototypes to non-existing functions.

 

Then, in complex.c:


struct complex a,b,c;

When you've typedef'd the struct there's no need for the struct keyword. These global variables are also never used and should be removed.

 


complex getcomplex(char *input){
    
    char input[20];
    complex a,b;

    scanf("%s",&input);
	sscanf(input, "%lf+%lf", &real, &img);

}

The function `getcomplex` takes a string (pointer to char) as argument, presumably the string to be parsed? Why do you declare a new array, also called input and read user input with scanf? Also, there's only a single complex number to be parsed, so no need for a `a` and a  `b`. You should explicitly point sscanf to the struct members. And you have to actually return the parsed complex.

 


complex sum(double real, double img){
   
    complex c;
   
    c.real = a.real + b.real;
    c.img = a.img + b.img;

    printf("Hasil operasi penjumlahan bilangan kompleks = %d + %di", c.real, c.img);
    return (c);

}

This function is supposed to sum 2 complex numbers `a` and `b`. Why does it take 2 doubles `real` and `im` as arguments?

The printf specifier to print doubles is `%lf`, not `%d`.

 

Similar problems plague the other functions in complex.c

 

In main.c


    char ch,p,q,r;

    p = argv[1];
    q = argv[2];
    r = argv[3];

`argv` is a array of pointers to char, not char.

 


   switch(ch){

case 'sum':
    sum(getcomplex(q),getcomplex(r));
    break;

case 'substract':
    substract(getcomplexA(q),getcomplexB(r));
    break;

case 'multiply':
    multiply(getcomplexA(q),getcomplexB(r));
    break;

case 'divide':
    divide(getcomplexA(q),getcomplexB(r));
    break;

    }

You cannot switch on an entire string. Comparing strings has to be done with a function like `strcmp`. Also, strings require double quotes.

 

Final modified program, complex.h:


#ifndef COMPLEX_H_INCLUDED
#define COMPLEX_H_INCLUDED

typedef struct
{
    double real;
    double img;
} complex;

complex getcomplex(const char *input);
complex sum(complex a, complex b);
complex subtract(complex a, complex b);
complex multiply(complex a, complex b);

#endif // COMPLEX_H_INCLUDED

complex.c:


#include <stdio.h>
#include "complex.h"

complex getcomplex(const char *input)
{
    complex a;
    sscanf(input, "%lf+%lf", &a.real, &a.img);
    return a;
}


complex sum(complex a, complex b)
{
    complex c;
   
    c.real = a.real + b.real;
    c.img = a.img + b.img;

    printf("Hasil operasi penjumlahan bilangan kompleks = %lf + %lfi\n", c.real, c.img);
    return c;
}

complex subtract(complex a, complex b)
{
    complex c;

    c.real = a.real - b.real;
    c.img = a.img - b.img;

    printf("Hasil operasi pengurangan bilangan kompleks = %lf - %lfi\n", c.real, c.img);
    return c;
}

complex multiply(complex a, complex b)
{
    complex c;

    c.real = a.real*b.real - a.img*b.img;
    c.img = a.img*b.real + a.real*b.img;

    printf("Hasil operasi perkalian bilangan kompleks = %lf + %lfi\n", c.real, c.img);
    return c;
}

main.c:


#include <stdio.h>
#include <string.h>
#include "complex.h"

int main(int argc, char *argv[])
{

    if (argc < 4 || argc > 5)
    {
    	printf("Tolong masukan minimal 4 argumen. //ex. namafile arg1 arg2\n");
    	return 0;
    }

    const char operator = argv[1][0];
    const char* q = argv[2];
    const char* r = argv[3];

    switch(operator)
    {
        case '+':
        sum(getcomplex(q),getcomplex(r));
        break;

        case '-':
        subtract(getcomplex(q),getcomplex(r));
        break;

        case 'x':
        multiply(getcomplex(q),getcomplex(r));
        break;
    }
}

The `divide` function was removed and implementing it is left as an exercise.

Example command line:


./test_complex + 5+3i 7+2i

output:


Hasil operasi penjumlahan bilangan kompleks = 12.000000 + 5.000000i

 

I read it, and actually understands now how it actually works (thanks a lot btw!), and trying to debug but still no success because of "Undefined reference to WinMain@16". Did restart Code:Blocks, restart my laptop. Even changing my IDE to Visual Studio Code, still nothing.

 

Any ideas of this?

Humor me, as you should do.

 

Daily drivers, below.

 

Diccbudd PC

Intel Xeon E3-1225 v2 || ASRock B75M Motherboard || MSI GeForce GTX 1650 Gaming X 4G || Hynix 2x8 GB DDR3 1600 MHz RAM || 480 GB Pioneer APS-SL3 SATA SSD // 1 TB Seagate 2.5" HDD || be quiet! System Power 9 500 W PSU || Cooler Master T20 CPU Cooler || Samsung S19D300 Monitor || Fantech X6 Knight Mouse || VortexSeries VX7 Pro Keyboard

 

Samsung Galaxy A34 5G

8GB RAM, 256GB Internal Storage, 128GB SanDisk Extreme, and you could find the rest of the specs on the interwebz lol

 

Lenovo ThinkPad L390 Yoga

Intel Core i5-8365U || 8 + 16 GB DDR4 (don't ask, gf bought me the 16 GB RAM as my birthday present lol) || Samsung 256GB SSD

 

Personal Server: CasaOS, Home Assistant, ESPHome, Jellyfin.

AMD E-350 || 3GB DDR3 || 120GB random SSD || 1TB Toshiba HDD

 

Audio

Redmi TV Soundbar || KZ EDX Ultra + KZ APTX Bluetooth Module || JCALLY JM6 CX31933 DAC

Link to comment
Share on other sites

Link to post
Share on other sites

Another one, either.

When I try to compile main.c, it seems it can't read the header file. Because of:

image.png.f916dd793dd48e34f7a9adc9cef64768.png

 

Already changing the name, but still no any good response.

Any ideas either of this?

Humor me, as you should do.

 

Daily drivers, below.

 

Diccbudd PC

Intel Xeon E3-1225 v2 || ASRock B75M Motherboard || MSI GeForce GTX 1650 Gaming X 4G || Hynix 2x8 GB DDR3 1600 MHz RAM || 480 GB Pioneer APS-SL3 SATA SSD // 1 TB Seagate 2.5" HDD || be quiet! System Power 9 500 W PSU || Cooler Master T20 CPU Cooler || Samsung S19D300 Monitor || Fantech X6 Knight Mouse || VortexSeries VX7 Pro Keyboard

 

Samsung Galaxy A34 5G

8GB RAM, 256GB Internal Storage, 128GB SanDisk Extreme, and you could find the rest of the specs on the interwebz lol

 

Lenovo ThinkPad L390 Yoga

Intel Core i5-8365U || 8 + 16 GB DDR4 (don't ask, gf bought me the 16 GB RAM as my birthday present lol) || Samsung 256GB SSD

 

Personal Server: CasaOS, Home Assistant, ESPHome, Jellyfin.

AMD E-350 || 3GB DDR3 || 120GB random SSD || 1TB Toshiba HDD

 

Audio

Redmi TV Soundbar || KZ EDX Ultra + KZ APTX Bluetooth Module || JCALLY JM6 CX31933 DAC

Link to comment
Share on other sites

Link to post
Share on other sites

1 hour ago, dhannemon13 said:

Another one, either.

When I try to compile main.c, it seems it can't read the header file. Because of:

image.png.f916dd793dd48e34f7a9adc9cef64768.png

 

Already changing the name, but still no any good response.

Any ideas either of this?

 

1 hour ago, dhannemon13 said:

I read it, and actually understands now how it actually works (thanks a lot btw!), and trying to debug but still no success because of "Undefined reference to WinMain@16". Did restart Code:Blocks, restart my laptop. Even changing my IDE to Visual Studio Code, still nothing.

 

Any ideas of this?

Nevermind on both. Already make it works by assigning the files to a project on CodeBlocks.

Thread solved, then.

 

Thanks a lot @Unimportant, you really saved my time and day (presumably my programming practice score either lol).

Humor me, as you should do.

 

Daily drivers, below.

 

Diccbudd PC

Intel Xeon E3-1225 v2 || ASRock B75M Motherboard || MSI GeForce GTX 1650 Gaming X 4G || Hynix 2x8 GB DDR3 1600 MHz RAM || 480 GB Pioneer APS-SL3 SATA SSD // 1 TB Seagate 2.5" HDD || be quiet! System Power 9 500 W PSU || Cooler Master T20 CPU Cooler || Samsung S19D300 Monitor || Fantech X6 Knight Mouse || VortexSeries VX7 Pro Keyboard

 

Samsung Galaxy A34 5G

8GB RAM, 256GB Internal Storage, 128GB SanDisk Extreme, and you could find the rest of the specs on the interwebz lol

 

Lenovo ThinkPad L390 Yoga

Intel Core i5-8365U || 8 + 16 GB DDR4 (don't ask, gf bought me the 16 GB RAM as my birthday present lol) || Samsung 256GB SSD

 

Personal Server: CasaOS, Home Assistant, ESPHome, Jellyfin.

AMD E-350 || 3GB DDR3 || 120GB random SSD || 1TB Toshiba HDD

 

Audio

Redmi TV Soundbar || KZ EDX Ultra + KZ APTX Bluetooth Module || JCALLY JM6 CX31933 DAC

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×