#include <stdio.h>

typedef struct ComplexNumber_S
{
    float realNumber;
    float img;
} ComplexNumber;

/**
* @brief gets a number
* @return the input number
*/
float GetNumber()
{
    float num;
    while (scanf_s("%f", 9, &num) != 1)
    {
        while (getchar() != '\n');
        printf("Try again: ");
    }
    return num;
}

/**
*  Getting a char from user
*  @return a char
*/
char GettingOperator()
{
    printf("Enter operator: +, -, *, /, any other chars \n");
    char operatorr;
    operatorr = getchar();
    return operatorr;
}

/**
*   Getting a string, asks for real or complex 
*   @return string 
*/
char * GettingType()
{
    char type[8];
    printf("Enter number type: put: real or complex!\n");
    fgets(type, sizeof(type), stdin);
    return type;

}

/**
*   Getting a complex or real number
*   @param - type: real number or complex
*/
ComplexNumber GettingComplexNumber(char *type)
{
    ComplexNumber result;
    result.realNumber = 0.0;
    result.img = 0.0;
    if (type == "real")
    {
        printf("Enter a number\n");
        result.realNumber = GetNumber();
        result.img = 0.0;
    }

    if (type == "complex")
    {
        printf("Enter real number");
        result.realNumber = GetNumber();
        printf("Enter image field");
        result.img = GetNumber();

    }
    return result;
}

/**
*   @param num1 -  a complex number a + bi
*   @param num2 - a commplex number c + di
*
*   @return num1 / num2
*   formula: (ac + bd) / (c^2 + d^2) + i((bc - ad) / (c^2 + d^2))
*/
ComplexNumber Devision(ComplexNumber num1, ComplexNumber num2)
{
    ComplexNumber result;
    float denominator = num2.realNumber * num2.realNumber + num2.img * num2.img;
    result.realNumber = (num1.realNumber * num2.realNumber + num1.img * num2.img) / 
        denominator;
    result.img = (num1.img * num2.realNumber - num1.realNumber * num2.img) /
        denominator;
    return result;

}

/**
*  @param num1 - a + bi
*  @param num2 - c + di
*  @return a complex number 
*  formula:  ac - bd + i(ad + bc)
*/
ComplexNumber Multiplicate(ComplexNumber num1, ComplexNumber num2)
{
    ComplexNumber result;
    result.realNumber = num1.realNumber * num2.realNumber - num1.img * num2.img;
    result.img = num1.realNumber * num2.img + num1.img * num2.realNumber;
    return result;

}

/**
*  
*  @param num1 - a complex number
*  @param num2 - a complex number
*
*  @return num1 - num2 in a complex number
*/
ComplexNumber OperatorMinus(ComplexNumber num1, ComplexNumber num2)
{
    ComplexNumber result;
    result.realNumber = num1.realNumber - num2.realNumber;
    result.img = num1.img - num2.img;
    return result;

}

/**
*  adding two complex numbers.
*  @param num1 - a complex nnumber
*  @param num2 - a complex number
*
*/
ComplexNumber OperatorPlus(ComplexNumber num1, ComplexNumber num2)
{
    ComplexNumber result;
    result.realNumber = num1.realNumber + num2.realNumber;
    result.img = num1.img + num2.img;
    return result;

}

void PrintComplexNumber(ComplexNumber num)
{
    if (num.img > 0.0)
    {
        printf("%.2f + %.2fi", num.realNumber, num.img);
    }
    else
    {
        printf("%.2f  %.2fi", num.realNumber, num.img);
    }
}

/**
*         calculator of complex and real numbers
* @return 0 - when terminates
*/
int main()
{
    char *type;
    type = GettingType();
    ComplexNumber num1 = GettingComplexNumber(type);
    
    char operatorr;
    int ext = 0;
    ComplexNumber num2;
    
    while (ext == 0)
    {
        operatorr = GettingOperator();
        type = GettingType();
        num2 = GettingComplexNumber(type);
        switch (operatorr)
        {
        case '+':
            num1 = OperatorPlus(num1, num2);
            break;
        case '*':
            num1 = Multiplicate(num1, num2);
            break;
        case '/':
            num1 = Devision(num1, num2);
            break;
        case '-':
            num1 = OperatorMinus(num1, num2);
            break;
        default:
            ext = 1;
            break;

        }
    }
    
    PrintComplexNumber(num1);
    return 0;
}

Hai!

Saya mencoba membuat kalkulator bilangan kompleks tetapi masalahnya adalah saya meneruskan char * yang diinisialisasi ke suatu fungsi dan memperlakukannya sebagai null.

Saya tidak mengerti mengapa fungsi GettingComplexNumber(char *type) menganggap variabel type sebagai null alih-alih string yang telah saya lewati sebelumnya.

Sebagai contoh, saya memberikan input real. Ketika saya men-debug, saya perhatikan bahwa type = '/0' alih-alih apa yang saya inginkan menjadi "nyata", jadi, kondisinya type == "real" salah

Bagaimana saya bisa memecahkan masalah ini?

0
אסף דוד הלל 9 Januari 2021, 21:56

3 jawaban

Jawaban Terbaik

Ada beberapa masalah dalam kode Anda:

  1. Anda mengembalikan referensi ke variabel lokal di GettingType. Saya akan merekomendasikan menggunakan nilai konstan sehingga angka ajaib tidak akan muncul dan dialokasikan secara dinamis. Jangan lupa lakukan #include <stdlib.h>

  2. Anda tidak dapat membandingkan string dengan ==. Membandingkan dengan == memeriksa alamat memori tempat string disimpan, tidak ada nilai yang disimpan di dalamnya. Anda dapat menggunakan fungsi strcmp dari string.h sebagai gantinya. strcmp akan membandingkan kemudian menurut abjad dan mengembalikan 0 jika keduanya sama.

  3. Anda membaca dengan fgets. '\n' disimpan dalam larik Anda. Jadi bahkan jika Anda bisa memeriksa dengan == itu tidak akan sama. Anda harus membandingkan dengan real\n dan complex\n.

  4. Anda belum mengosongkan buffer sebelum memanggil GettingOperator() sehingga membaca '\n' yang tersisa setelah membaca nomor float.

  5. Setelah membaca operator Anda membaca type lagi. Jadi, Anda harus menambahkan getchar() ekstra untuk \n.

  6. Parameter di scanf_s Anda salah. Angka 9 itu seharusnya tidak ada. Anda dapat membatasinya dengan meletakkannya setelah %.

  7. Anda meminta informasi kepada pengguna dan lupa memberi spasi setelah Anda mengirim pesan.

  8. Pesan Anda tidak jelas bahwa untuk keluar dari program Anda harus memasukkan operator yang tidak valid. Saya harus mengetahuinya dengan melihat defaultdi sakelar Anda.

  9. Bahkan jika saya memberikan operator yang tidak valid, kode Anda meminta nomor kedua. Seharusnya tidak karena operator tidak valid.

Saya telah membuat sebagian besar perubahan yang disarankan. Namun, Anda masih perlu memvalidasi input pengguna. Misalnya: apa yang akan terjadi jika pengguna mengetikkan sesuatu yang bukan real atau complex dan hal-hal seperti itu. Berikut adalah hasil setelah perubahan:

#include <stdio.h>
#include <string.h>
#include<stdlib.h>
#define STRING_SIZE 15
typedef struct ComplexNumber_S
{
    float realNumber;
    float img;
} ComplexNumber;

/**
* @brief gets a number
* @return the input number
*/
float GetNumber()
{
    float num;
    while (scanf_s("%f", &num) != 1)
    {
        while (getchar() != '\n');
        printf("Try again: ");
    }
    return num;
}

/**
*  Getting a char from user
*  @return a char
*/
char GettingOperator()
{
    printf("Enter operator: +, -, *, /, (any other chars to leave the program)\nYour choice: ");
    char operatorr;
    operatorr = getchar();
    getchar(); // You need to get the \n so it won't cause trouble when reading another char or string
    return operatorr;
}

/**
*   Getting a string, asks for real or complex
*   @return string
*/
char* GettingType()
{
    char* type = (char*)malloc(sizeof(*type) * STRING_SIZE);;
    printf("Enter number type: put: real or complex!\nYour choice: ");
    fgets(type, STRING_SIZE, stdin);
    return type;

}

/**
*   Getting a complex or real number
*   @param - type: real number or complex
*/
ComplexNumber GettingComplexNumber(char* type)
{
    ComplexNumber result;
    result.realNumber = 0.0;
    result.img = 0.0;
    if (!strcmp(type, "real\n"))
    {
        printf("Enter a real number: \n");
        result.realNumber = GetNumber();
        result.img = 0.0;
    }

    if (!strcmp(type, "complex\n"))
    {
        printf("Enter a real number for the real part: ");
        result.realNumber = GetNumber();
        printf("Enter a real number for the imaginary part: ");
        result.img = GetNumber();

    }
    getchar(); // since you are reading a char as operator you need to catch the '\n' here also
    return result;
}

/**
*   @param num1 -  a complex number a + bi
*   @param num2 - a commplex number c + di
*
*   @return num1 / num2
*   formula: (ac + bd) / (c^2 + d^2) + i((bc - ad) / (c^2 + d^2))
*/
ComplexNumber Devision(ComplexNumber num1, ComplexNumber num2)
{
    ComplexNumber result;
    float denominator = num2.realNumber * num2.realNumber + num2.img * num2.img;
    result.realNumber = (num1.realNumber * num2.realNumber + num1.img * num2.img) /
        denominator;
    result.img = (num1.img * num2.realNumber - num1.realNumber * num2.img) /
        denominator;
    return result;

}

/**
*  @param num1 - a + bi
*  @param num2 - c + di
*  @return a complex number
*  formula:  ac - bd + i(ad + bc)
*/
ComplexNumber Multiplicate(ComplexNumber num1, ComplexNumber num2)
{
    ComplexNumber result;
    result.realNumber = num1.realNumber * num2.realNumber - num1.img * num2.img;
    result.img = num1.realNumber * num2.img + num1.img * num2.realNumber;
    return result;

}

/**
*
*  @param num1 - a complex number
*  @param num2 - a complex number
*
*  @return num1 - num2 in a complex number
*/
ComplexNumber OperatorMinus(ComplexNumber num1, ComplexNumber num2)
{
    ComplexNumber result;
    result.realNumber = num1.realNumber - num2.realNumber;
    result.img = num1.img - num2.img;
    return result;

}

/**
*  adding two complex numbers.
*  @param num1 - a complex nnumber
*  @param num2 - a complex number
*
*/
ComplexNumber OperatorPlus(ComplexNumber num1, ComplexNumber num2)
{
    ComplexNumber result;
    result.realNumber = num1.realNumber + num2.realNumber;
    result.img = num1.img + num2.img;
    return result;

}

void PrintComplexNumber(ComplexNumber num)
{
    if (num.img > 0.0)
    {
        printf("%.2f + %.2fi\n", num.realNumber, num.img);
    }
    else
    {
        printf("%.2f  %.2fi\n", num.realNumber, num.img);
    }
}

/**
*         calculator of complex and real numbers
* @return 0 - when terminates
*/
int main()
{
    char* type;
    type = GettingType();
    ComplexNumber num1 = GettingComplexNumber(type);

    char operatorr;
    int ext = 0;
    ComplexNumber num2;

    while (ext == 0)
    {
        operatorr = GettingOperator();

        //If the user didn't type one of the operators below then break the loop
        if (!strchr("+-/*", operatorr))
            break;
        type = GettingType();
        num2 = GettingComplexNumber(type);
        switch (operatorr)
        {
        case '+':
            num1 = OperatorPlus(num1, num2);
            break;
        case '*':
            num1 = Multiplicate(num1, num2);
            break;
        case '/':
            num1 = Devision(num1, num2);
            break;
        case '-':
            num1 = OperatorMinus(num1, num2);
            break;
        }
    }

    PrintComplexNumber(num1);
    return 0;
}

Saya kira Anda menggunakan Visual Studio. Jika demikian, Anda dapat menguji kode Anda dalam mode Debug dan melihat apa yang disimpan di setiap variabel, menjalankan satu pernyataan pada satu waktu. Tekan terus tekanF11 (itulah jalan pintas di Visual Studio 2019), lihat apa yang terjadi dan bandingkan dengan apa yang menurut Anda seharusnya terjadi. Itu mungkin menghemat banyak waktu!

1
vmp 9 Januari 2021, 19:55

Pada fungsi GettingType Anda, Anda mendeklarasikan char type[8];. Ini menyimpan type di tumpukan, dan karena itu, ketika fungsi berakhir, memori hilang. Sebagai gantinya, Anda perlu menyimpan type di heap menggunakan malloc, yang akan menyimpan data bahkan setelah fungsi berakhir. Pertimbangkan kode ini:

char * GettingType()
{
    char *type = (char*)malloc(sizeof(char)*8);
    printf("Enter number type: put: real or complex!\n");
    fgets(type, 8, stdin);
    return type;
}
3
Gal Birka 9 Januari 2021, 19:21

Tidak yakin mengapa Anda mendapatkan "null", (EDIT: Lihat Jawaban @ Birkagal mengapa Anda mendapatkan nol) pasti ada masalah dengan GettingType daripada GettingComplexNumber. Saya tidak dapat menguji karena Anda menggunakan scanf_s dan tampaknya khusus untuk Windows.

Tapi selain itu, Anda tidak dapat membandingkan string dengan ==, ini hanya membandingkan alamat pointer. Sebagai gantinya, Anda perlu menggunakan fungsi strcmp standar untuk perbandingan string.

1
Omer Tuchfeld 9 Januari 2021, 19:01