简体   繁体   中英

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

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 “CVPVPVPVP .”, 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?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM