简体   繁体   English

C ++ while循环奇怪的行为

[英]C++ while loop strange behaviour

I am writing a piece of code in C++ that takes a char array as input which contains a JSON-like text. 我正在用C ++写一段代码,将一个char数组作为输入,其中包含一个类似JSON的文本。 The idea is to get the values from that JSON. 这个想法是从JSON获取值。

The function that is giving the error is the following: 给出错误的函数如下:

variable * getVariableInfo(const char * variableInfo){
        /*get {...}*/
        printf("%s\n",variableInfo);
        int start, countWord=0;
        int order=-1, type=-1;
        char * value;
        variable * returnValue;
        const char * aux;
        while(*(variableInfo++)){
            if(*variableInfo=='"'){
                variableInfo++;
                aux=variableInfo;
                countWord=0;
                while(*(variableInfo++)!='"'){
                    countWord++;
                }
                char *word = (char *) calloc(1, sizeof(char) * ( countWord + 1 ) );
                strncpy(word, aux, countWord);
                word[countWord]='\0';
                printf("\nWORD %s", word);

                while(*(variableInfo++)!='"');
                aux=variableInfo;
                countWord=0;
                while(*(variableInfo++)!='"'){
                    countWord++;
                }
                char *str = (char *) calloc(1, sizeof(char) * ( countWord + 1 ) );
                strncpy(str, aux, countWord);
                str[countWord]='\0';
                printf("\nSTR %s\n",str);
                if(strcmp(word,ORDER)==0){
                        order=a2i(str);
                        printf("ORDER = %i", order);
                }
                /*TYPE*/
                else if(strcmp(word,TYPE)==0){
                        if(strcmp(str, valueINT)==0) type=TYPE_INT;
                        else if(strcmp(str, valueSTR)==0) type=TYPE_STRING;
                        else if(strcmp(str, valueBOOL)==0) type=TYPE_BOOLEAN;
                        else return 0;
                        printf("TYPE = %i", type);
                /*VALUE*/
                }
                else if(strcmp(word,VALUE)==0){
                        value =  (char *) calloc(1, sizeof(char) * ( countWord + 1 ) );
                        strncpy(value, str, countWord);
                        value[countWord]='\0';
                        printf("VALUE = %s", value);
                }
                else{
                        printf("ELSE");
                        return 0;
                }
            }
            printf("\nCHAR %c\n---------", *variableInfo);
        }

        printf("Pass");
        if(type==-1||order==-1||!value){
            if(!type) printf("NOT");
            if(!order) printf("NOO");
            if(!value) printf("NOV");
            return 0;
        } 
        returnValue = (variable *) calloc(1,sizeof(variable)+(sizeof(char)*(strlen(value)+1)));
        returnValue->order=order;
        returnValue->type=type;
        strncpy(returnValue->value,value,strlen(value));
        returnValue->value[strlen(value)]='\0';
        return returnValue;
}

The var "variableInfo" is sent from another function and is created like following from the aux pointer which contains the original full JSON-like text: 变量“ variableInfo”是从另一个函数发送的,并按照以下操作从aux指针创建,该aux指针包含原始的完整JSON式文本:

variableInfo = (char *) calloc(1, sizeof(char) * ( countWord + 1 ) );
strncpy(variableInfo, aux, countWord);
variableInfo[countWord]='\0';                               
variables[variableCount]=getVariableInfo(variableInfo);

As you can see, I added some printf and the output looks like the following: 如您所见,我添加了一些printf,输出如下所示:

{"ORDER":"0","TYPE":"int","VALUE":"9999"}

WORD ORDER
STR 0
ORDER = 0
CHAR ,
---------
WORD TYPE
STR int
TYPE = 0
CHAR ,
---------
WORD VALUE
STR 9999
VALUE = 9999
CHAR }
---------
CHAR 
Segmentation fault (core dumped)

I print the "variableInfo" variable and it shows the right piece of text that should be sent to the "getVariableInfo" function, then the values for ORDER, TYPE and VALUE are properly taken from the JSON-like text. 我打印了“ variableInfo”变量,它显示了应该发送到“ getVariableInfo”函数的正确文本,然后正确地从类似JSON的文本中获取ORDER,TYPE和VALUE的值。 However, I get the segmentation fault error, since the last round of the while, even if the last char is '\\0' it stays in the while loop (See output "CHAR }" should be last and next time that checks the while statement it should end it but it then prints "CHAR "). 但是,我得到了分段错误错误,因为while的最后一轮,即使最后一个char为'\\ 0',它也仍然停留在while循环中(请参阅输出“ CHAR}”应该是上一次,下一次检查while语句应该结束它,但随后显示“ CHAR”)。

Thanks for your help. 谢谢你的帮助。

Kind regards. 亲切的问候。

You are using the post-increment operator to increment variableInfo . 您正在使用后递增运算符来递增variableInfo This operator returns a copy of the old pointer value, which does not point to \\0 . 该运算符返回旧指针值的副本,该副本不指向\\0 Use pre-increment instead: 使用预增量代替:

while(*(++variableInfo))

Pre-increment will return the incremented value. 预增值将返回增值。 See this question for more info on pre- and post-increment. 有关增加前和增加后的更多信息,请参见此问题

In this case if I would debug I might choose to store the original value of 'variableinfo' and print 'variableinfo-originalPointer' - to get a sensable index value. 在这种情况下,如果我要调试,则可以选择存储'variableinfo'的原始值并打印'variableinfo-originalPointer'-以获取合理的索引值。

I don't have a C compiler handy but I do wonder about your while loops: Perhaps 我没有C编译器,但是我确实想知道您的while循环:也许

while (*(variableinfo++)=='"') 

Always increases 'variableinfo'. 总是增加'variableinfo'。 If that is so, it can be increased 3 times (three while-loops) before you check that the end of the string may be reached. 如果是这样,可以将其增加3倍(三个while循环),然后再检查是否可以到达字符串的末尾。 If that is the case, it can go past the end of the string, never detecting that it crosses the end of the string. 如果是这种情况,它可以越过字符串的结尾,而不会检测到它越过了字符串的结尾。

Solutions: (1) tear the whileloops apart to make the increment explicit, and (2) Always check for '\\0' when you increase your string-pointer: 解决方案:(1)将while循环拆开以使增量明确,(2)在增加字符串指针时始终检查“ \\ 0”:

while(*variableinfo == '"' && *variableinfo!='\0')
{
    variableinfo++;
}

and possibly: 并可能:

if ('\0' == *variableinfo)
    break;

to exit the outermost loop immediately. 立即退出最外层循环。

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

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