אסף דוד הלל
אסף דוד הלל

Reputation: 13

How to pass a string to function and then check if it is equal to a string

 #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;
}

Hi!

I tried to create a complex numbers calculator but the problem is that I pass an initialized char * to a function and it treats it as null.

I don't understand why the function GettingComplexNumber(char *type) considers the variable type as null instead of the string that I had passed before.

For example, I gave the input real. When I debugged, I noticed that type = '/0' instead of what I want it to be "real", so, the condition type == "real" is false

How can I solve this problem?

Upvotes: 0

Views: 71

Answers (3)

vmp
vmp

Reputation: 2420

There are few problems in your code:

  1. You are returning a reference to a local variable in GettingType. I'd recommend using a constant value so magic numbers wont appear and allocated dynamically. Don't forget do #include <stdlib.h>

  2. You can't compare strings with ==. Comparing with == checks the memory address where the string is stored, no the values stored on them. You can use the function strcmp from string.h instead. strcmp will compare then alphabetically and return 0 if they are equal.

  3. You are reading with fgets. The '\n' is saved in your array. So even if you could check with == it wouldn't be equal. You would have to compare with real\n and complex\n.

  4. You haven't emptied the buffer before calling GettingOperator() so it is reading the '\n' that was left after reading the float number.

  5. After reading operator you read a type again. So you should add an extra getchar() for the \n.

  6. The parameters in your scanf_s are wrong. That 9 shouldn't be there. You could limit that by putting it after the %.

  7. You are asking information to the user and forgetting to put a space after you message.

  8. Your messages aren't clear that to leave the program you should enter an invalid operator. I had to figure that by looking at the defaultin your switch.

  9. Even if I provide an invalid operator your code asks for the second number. It shouldn't since the operator is invalid.

I've made most of the changes suggested. However, you still need to validate user input. For example: what should happen if the user type something that is neither real nor complex and stuff like that. Here is the result after the changes:

#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;
}

I suppose you are using Visual Studio. If so, you can test your code in Debug mode and see what is being saved in each variable, executing one statement at a time. Just hit keep hittingF11 (thats the shortcut on Visual Studio 2019), see what is happening and compare to what you think should be happening. That might save you a lot of time!

Upvotes: 1

Gal Birka
Gal Birka

Reputation: 591

On your GettingType function, you declare char type[8];. This saves type in the stack, and therefore, when the function ends, the memory is lost. Instead, you need to save type in the heap using malloc, which will save the data even after the function ends. Consider this code:

char * GettingType()
{
    char *type = (char*)malloc(sizeof(char)*8);
    printf("Enter number type: put: real or complex!\n");
    fgets(type, 8, stdin);
    return type;
}

Upvotes: 3

Omer Tuchfeld
Omer Tuchfeld

Reputation: 3042

Not sure why you're getting "null", (EDIT: See @Birkagal's answer for why you're getting null) must be a problem with GettingType rather than GettingComplexNumber. I can't test because you're using scanf_s and it seems to be Windows-specific.

But that aside, you cannot compare strings with ==, this just compares the pointer address. Instead, you need to use the standard strcmp function for string comparison.

Upvotes: 1

Related Questions