Home > database >  An empty for loop fixed my code but I don't know how
An empty for loop fixed my code but I don't know how

Time:06-23

I’m trying to solve some exercises in preparation for an incoming test and i’ve encountered a problem that i’ve fixed by chance and i’d like to understand what’s going on with my code.

The exercise requires me to create a struct type that represent a monomial of 4 variables (x, y, w and z) and two functions, print_term that will show the monomial on screen and read_term, that take an user input and returns a monomial. The exercise requires the user input to be of the form “C V P V P V P V P .”, where C is the coefficient of the monomial, V is one of the 4 variables (in any order) and P is their power.

//Here is the monomial struct
struct term{
    int coef;
    int potx;
    int poty;
    int potw;
    int potz;
};

My problem lies in the read_term function: sometimes, if C is negative the power of one of the variables will be set to -48 (which definitely come from my attempt to convert the char that represent a digit to it’s value in int): for example, the input “-257 x 2 z 3 w 1 .” will return me -257(x^2)(w^-48)(z^3), while “257 x 2 z 3 w 1 .” will instead return the correct result 275(x^2)w(z^3).

struct term read_term(){
    struct term result;
        result.coef =0;
        result.potx =0;
        result.poty =0;
        result.potw =0;
        result.potz =0;
        
    char input[255];
    for(int i =0; i < sizeof(input)/sizeof(input[0]);i  ){
        input[i] = '\0';
    }
    char inputNeg[255];
    int negativo = 0;

    printf("Termine: \n");      
                            
    fgets(input, 255, stdin);
    input[strlen(input)-1] = '\0';      //should remove '\n'


    //I remeve the minus sign, i'll add it back in later.
    if(input[0] == '-'){

        negativo = 1;
        int i = 1;
        do{
            inputNeg[i-1] = input[i];
            i  ;
        }while(input[i] != '\0');   
        printf("\n%s\n", input);
        strcpy(input, inputNeg); 
        printf("\n%s\n", input);   
    }
   
    ////////////THIS MAKE OR BRAKE THE CODE
    
    //printf("\ninput prova\n");
    for(int i =0; i < sizeof(input)/sizeof(input[0]);i  ){
       //printf("%c", input[i]);
    }

    ////////////////////////////

    //Change struct term result based on input:
    int index = 0;
    int cifreCof[12];
    for(int j=0; j< sizeof(cifreCof)/sizeof(cifreCof[0]);j  ){
                cifreCof[j] = 0;
    }
    int temp = 0;
    int pot = 0;

    do{
        //Coeff is always at index 0
        if(index == 0){
            //Conversion from char to int
            do{
            cifreCof[index] = input[index] - '0';
            index  ;
            pot  ;
            }while(input[index] != ' ');

            //Puts all the digits in one int
            for(int i=0; i < sizeof(cifreCof)/sizeof(cifreCof[0]); i  ){
                temp = temp   (cifreCof[i]*pow(10, pot-1));
                pot--;
            }

            //Place the minus sign back.
            if(negativo == 0){
                result.coef = temp;
            }
            else{
                result.coef = (-1)*temp;
            }
           
        }
        // Variabili.
        else{
            //White space
            if(input[index] == ' '){
                index  ;
            }
            //x char
            else if(input[index] == 'x'){
                index  ;
                index  ;
                //per ora mi limito ad esponenti a una cifra
                if(input[index] != '.'){
                    result.potx = input[index] - '0';
                    index  ; 
                }
                else{index  ;}
            }
            //y char
            else if(input[index] == 'y'){
                index  ;
                index  ;
                //per ora mi limito ad esponenti a una cifra
                if(input[index] != '.'){
                    result.poty = input[index] - '0';
                    index  ; 
                }
                else{index  ;}
            }
            // w char
            else if(input[index] == 'w'){
                index  ;
                index  ;
                //per ora mi limito ad esponenti a una cifra
                if(input[index] != '.'){
                    result.potw = input[index] - '0';
                    index  ; 
                }
                else{index  ;}
            }
            //z char
            else if(input[index] == 'z'){
                index  ;
                index  ;
                //per ora mi limito ad esponenti a una cifra
                if(input[index] != '.'){
                    result.potz = input[index] - '0';
                    index  ; 
                }
                else{index  ;}
            }
            else{index  ;}
        }

    }while(input[index] != '\0');
       
    return result;
}

In an attempt to identify the problem, i placed a for loop to print the array i use to save the input, just to discover that this loop changed the outcome of the function to the correct result: i decided to keep the loop but emptying it of its code, and still the result is correct. I have no idea how it fix my code but it does. Any explanation?

CodePudding user response:

It is very unlikely the empty loop had anything to do with fixing your code. But undefined behavior may have played a role in exposing the problem.

When a variable is created, the contents of memory allocated is unknown. Therefore, if it is used before being initialized, the results will be unpredictable.

A simple initialization will work:

char inputNeg[255] = {0};//initializes all elements of array in one step.

Although the for loop does initialize the array here

char input[255];
for(int i =0; i < sizeof(input)/sizeof(input[0]);i  ){
    input[i] = '\0';
}

...initialization during declaration is more efficient:

char input[255] = {0};

Do the same for cifreCof

Regarding removing the newline after calling fgets, consider using this method:

//input[strlen(input)-1] = '\0';//unsafe for an empty string
input[strcspn(input, "\n")] = 0;//this is safe, and will remove newline
  •  Tags:  
  • c
  • Related