首页 > 解决方案 > C - 循环,输入未正确读取,仅打印出“不匹配”

问题描述

我目前正在编写一个读取 GPS 输入并将输入写入数组的程序。inChar2 是 UART2 的 getchar。它循环遍历字符串,直到找到字符 $GPPGA 行,然后将经度和纬度写入它们各自的数组。然后我想比较 longitude & check_longitude 和 latitude & check_latitude ,如果匹配则打印出一件事,如果不匹配则打印出另一件事。但是,我的代码没有比较字符串,只打印出“不匹配”。我哪里错了?我还编写了一个名为 accum 的函数,它接收所有 GPS 输入并将其存储在一个巨大的字符串中。我认为它没有正确编写,并且我没有在 ISR 功能中使用它。这个程序是在 MPLAB X IDE 中编写的。

    //accumulate variables
void accum(char c) 
{
    static char array[1000];
    static char *end = array;
    *end++ = c;
    if (c == "\n") 
    {
        *end++ = 0; 
        end = array;
    }
}

void _ISR _U2RXInterrupt() 
{
    //setting up the variables used
    unsigned char incomer_data = 0;
    unsigned char longitude[13] = {};
    unsigned char latitude[13] = {};
    unsigned char array_count = 0;

    unsigned char temp;

    int is_in = 0;

    //$GPGGA,224355.00,3326.51776,N,08849.74254,W,2,09,1.02,104.9,M,-29.5,M,,0000*64

    unsigned char check_long[13] =
    {   //"3327.12050,N", //sidewalk 
        "3326.51776",
    };
    unsigned char check_lat[13] = 
    {
        //"08847.25265W",
        "08849.74254",
    };

    accum(temp);
    // printf("%c", temp);
    //char c = inChar2();
    //outChar(c);
    while (1)
    {
        incomer_data = inChar2();      //get character, checking string $GPGGA
        //outChar(incomer_data);

        //step by step find the GPGGA line
        if (incomer_data == '$') 
        { 
            //first statement of GPS data starts with $
            incomer_data = inChar2(); //if the first IF becomes true then next phase
            //    outChar(incomer_data);

            if (incomer_data == 'G') 
            {
                incomer_data = inChar2();
                //outChar(incomer_data);

                if (incomer_data == 'P') 
                {
                    incomer_data = inChar2();
                    //outChar(incomer_data);

                    if (incomer_data == 'G') 
                    {
                        incomer_data = inChar2();    
                        //outChar(incomer_data);

                        if (incomer_data == 'G') 
                        {
                            incomer_data = inChar2();
                            //outChar(incomer_data);

                            if (incomer_data == 'A')
                            {
                                incomer_data = inChar2();
                                //outChar(incomer_data);

                                if (incomer_data == ',')
                                { 
                                    // first ',' received  
                                    incomer_data = inChar2(); //at this stage Final check in done. GPGGA is found
                                    //outChar(incomer_data);
                                    while (incomer_data != ',') 
                                    { //skipping GMT time
                                        incomer_data = inChar2();
                                        //outChar(incomer_data);
                                    }
                                    incomer_data = inChar2();
                                    latitude[0] = incomer_data;
                                    //outChar(incomer_data);
                                    // printf("working\n");

                                    while (incomer_data != ',') 
                                    {
                                        //printf("hi\n");
                                        for(array_count = 1; incomer_data != 'N'; array_count++) 
                                        {
                                            incomer_data = inChar2();
                                            latitude[array_count] = incomer_data; //Store Latitude data
                                            outChar(incomer_data);
                                            //printf("latitude data");
                                        }
                                        //printf("hi");
                                        incomer_data = inChar2();
                                        if (incomer_data == ',') 
                                        {
                                            for(array_count = 0; (incomer_data != 'E'); array_count++) 
                                            {
                                                incomer_data = inChar2();
                                                longitude[array_count] = incomer_data; //store Longitude data
                                                outChar(incomer_data);
                                                //printf("longitude data");
                                            }
                                        }

                                        int i = 0;
                                        for (i = 0; i < 13; ++i) 
                                        {
                                            if ((strcmp(check_long, longitude) == 0) & (strcmp(check_lat, latitude) == 0)) {
                                                printf("hot, sidewalk, bright, sunny, weird\n");
                                                is_in = 1;
                                            }
                                        }

                                        if (is_in == 0) 
                                        { 
                                            printf("no match");
                                        }
                                        array_count = 0;
                                        while (array_count < 12) { //array of latitude data is 11 digit
                                            //print data 
                                            array_count++;
                                        }
                                        array_count = 0;
                                        while (array_count < 13) { //array of longitude data is 12 digit
                                            //print data
                                            array_count++;
                                        }
                                        outChar(incomer_data); //prints out E
                                    }
                                }
                            }     
                        }
                    }
                }
            }
            for(array_count = 0; array_count <= 13; array_count++)
            {
                incomer_data = 0;
                latitude[array_count] = 0;
                longitude[array_count] = 0;
            }
            array_count = 0;
        }
    }  

    //DELAY_MS(3000);
}

标签: c

解决方案


以下是查看您发布的代码后的一些注意事项:

添加您要比较的字符串到您的“不匹配” printf,以防您得到一些不是完全匹配的合理内容(即“3326.51758”!=“3326.51756”,尽管由于抖动它仍然看起来很合理)。

您的 unsigned char temp 未经初始化就被传递给 accum,因此它的堆栈垃圾和 accum 函数可能无法按预期工作。

您的 is_in 标志可以设为 unsigned char 以节省 1-3 个字节,这没什么大不了的,但是每个字节都很重要。

check_long/check_lat 应该是 const 全局变量,这样你就不会在每次调用时在 ISR 堆栈上重新分配它们,更重要的是因为它们是“只读的”,即 const。

如果您确定“$”符号表示新 GPS 输入的开始,您可以/应该使用“$”进入读取 GPPDA 标签其余部分的状态机,类似于嵌套的 ifs,但可能会切换失败更具可读性(如果您讨厌失败,即使它们被评论,也可以循环切换)

我假设 inChar2 只是从寄存器中读取,因为这看起来像是一个 PIC,它可能类似于 U2RXREG。我会避免添加这么多 inChar2 调用,而直接从寄存器中读取。

您不需要在底部进行 for 循环将所有这些变量设置为 0,它们应该只是从堆栈中弹出并在下次通过此 ISR 获得串行/UART 流量时重新初始化为零。

归根结底,您真的不想将双精度值存储为字符串(您希望它们作为双精度值!)如果您想测试您的输入,将经纬度值存储为双精度值,然后对您的测试值进行 inside_epsilon 比较和输入。这可能对你有帮助,GL Converting char* to float or double


推荐阅读