C++ while循环奇怪的行为

Posted

技术标签:

【中文标题】C++ while循环奇怪的行为【英文标题】:C++ while loop strange behaviour 【发布时间】:2017-05-30 08:13:28 【问题描述】:

我正在用 C++ 编写一段代码,该代码将 char 数组作为输入,其中包含类似 JSON 的文本。我们的想法是从该 JSON 中获取值。

给出错误的函数如下:

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;

var "variableInfo" 是从另一个函数发送的,并且是从包含原始完整的类 JSON 文本的 aux 指针创建的:

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

如您所见,我添加了一些 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)

我打印“variableInfo”变量,它显示了应该发送到“getVariableInfo”函数的正确文本,然后从类似 JSON 的文本中正确获取 ORDER、TYPE 和 VALUE 的值。但是,我得到了分段错误错误,因为最后一轮 while,即使最后一个 char 是 '\0' 它仍停留在 while 循环中(请参阅输出“CHAR ”应该是最后一次和下一次检查 while声明它应该结束它,但它会打印“CHAR”)。

感谢您的帮助。

亲切的问候。

【问题讨论】:

与您的问题完全无关,但这是用于遍历 json 字符串的大量代码。如果可能,请考虑另一种方法。 这看起来更像 C 而不是 C++ 但是,我得到了分段错误错误, -- 对于所有 C 代码,这并不奇怪。 std::stringstd::vector的用法在哪里?如果是 JSON,请考虑使用 JSON 库,不要尝试自己解析此代码。 您好,感谢您的回复。我尝试创建自己的 JSON 的原因是我在有限的环境中工作。但是,我再次检查了环境,似乎我也可以在那里使用字符串和向量,所以我会尝试使用它们。感谢您的帮助:) 【参考方案1】:

您正在使用后自增运算符来增加variableInfo。此运算符返回旧指针值的副本,它不指向\0。改为使用预增量:

while(*(++variableInfo))

预增量将返回增量值。 请参阅this question 了解有关前增量和后增量的更多信息。

【讨论】:

您好,我尝试了您的解决方案,但仍然出现错误。感谢您的回复:)【参考方案2】:

在这种情况下,如果我要调试,我可能会选择存储 'variableinfo' 的原始值并打印 'variableinfo-originalPointer' - 以获得合理的索引值。

我手边没有 C 编译器,但我确实想知道您的 while 循环: 也许

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

总是增加'variableinfo'。如果是这样,在检查是否可以到达字符串末尾之前,可以将其增加 3 倍(三个 while 循环)。 如果是这种情况,它可以越过字符串的末尾,而永远不会检测到它越过字符串的末尾。

解决方案:(1) 将 while 循环分开以使增量显式,以及 (2) 在增加字符串指针时始终检查 '\0':

while(*variableinfo == '"' && *variableinfo!='\0')

    variableinfo++;

并且可能:

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

立即退出最外层循环。

【讨论】:

感谢您的回复,我尝试实施您的解决方案,但仍然出现错误。正如我之前所说的,我可以在有限的环境中使用字符串和向量,所以我想我会尝试一下。谢谢你的时间:)

以上是关于C++ while循环奇怪的行为的主要内容,如果未能解决你的问题,请参考以下文章

在while循环中继续的奇怪行为

c++中while循环的意外行为

循环中的 Cout 奇怪的行为

R中的for循环与while循环

循环中的列表行为非常奇怪

While 循环奇怪地响应非整数