简体   繁体   English

一个空的 for 循环修复了我的代码,但我不知道如何

[英]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.练习要求我创建一个结构类型,它表示 4 个变量(x、y、w 和 z)的单项式和两个函数,print_term 将在屏幕上显示单项式,read_term 接受用户输入并返回单项式。 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.该练习要求用户输入的格式为“CVPVPVPVP”,其中 C 是单项式的系数,V 是 4 个变量之一(以任意顺序),P 是它们的幂。

//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 .”我的问题在于 read_term 函数:有时,如果 C 为负,则其中一个变量的幂将设置为 -48(这肯定来自我尝试将表示数字的 char 转换为 int 中的值):对于例如,输入“-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 .”将返回-257(x^2)(w^-48)(z^3),而“257 x 2 z 3 w 1”。 will instead return the correct result 275(x^2)w(z^3).而是返回正确的结果 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.为了确定问题,我放置了一个 for 循环来打印我用来保存输入的数组,只是为了发现这个循环将函数的结果更改为正确的结果:我决定保留循环但清空它它的代码,结果仍然是正确的。 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虽然 for 循环确实在这里初始化了数组

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 cifreCofcifreCof做同样的事情

Regarding removing the newline after calling fgets , consider using this method :关于调用fgets后删除换行符,请考虑使用此方法

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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