即使IF语句为false,字符指针数组也会被写入

问题描述 投票:-4回答:1

我正在通过指定的分隔符分解字符串并尝试根据第一个字符串修改typedef结构。我意识到当我逐步执行代码时,即使if语句变为false,也会写入typedef结构。我希望它能保留以前的for循环迭代中的旧值,但事实并非如此。 我还在考虑创建保存str的值的局部字符变量,以便我相应地更新它们并将它们的值赋给coord typedef。但后来似乎创造了太多变量。

我的愿望是只有当字符串以某个字符串开头时才让typedef更新标题。否则,打印headingPrev中可用的内容。

typedef struct {
    char* utc;
    char* lat;
    char* lat_dir;
    char* lon;
    char* lon_dir;
    char* speed_kn;
    char* heading;
} CoordinatesHandleTypeDef;

const char *str_gprmc[7] = {
    "$GPRMC,125812.50,A,5741.1245547,N,01158.9460229,E,10.324,207.1,270319,0.0,E,A*0F",
    "$GPRMC,130019.00,A,5741.5393572,N,01158.6608248,E,14.013,331.8,270319,0.0,E,A*0F",
    "$GPRMC,130019.50,A,5741.5414303,N,01158.6591608,E,15.498,331.8,270319,0.0,E,A*07",
    "$GPHDT,3.0979,T*01",
    "$GPRMC,130132.00,A,5741.6055487,N,01158.3862843,E,9.536,174.0,270319,0.0,E,A*35",
    "$GPRMC,130132.50,A,5741.6042334,N,01158.3862498,E,10.783,172.1,270319,0.0,E,A*00",
    "$GPHDT,357.8596,T*06"
};

CoordinatesHandleTypeDef coord = {0};

    // Loop through for every string that comes in. Imitate USART End of Line....then process the string

    // We gonna keep the heading parameter out of the loop to get updated only once the data is available
    // This is because according to the datasheet, its updated onchanged. i.e when there is a detection in heading mismatches
    char* headingPrev = NULL;
    uint8_t* str[8] = { NULL };
    uint8_t temp[50] = { NULL };

    for (size_t k = 0; k < ARRAY_SIZE(str_gprmc); k++)
    {
        size_t maxStorableTokens = 0;

        // store the string in a local variable to avoid access violation exceptions for read/write operations
        strcpy(temp, str_gprmc[k]);

        for (uint8_t *ptr_token = strtok(temp, ","); ptr_token; ptr_token = strtok(NULL, ","))
        {
            if (maxStorableTokens >= 0x08) break;

            str[maxStorableTokens++] = ptr_token;
        }

        // if the string at index[0] is $GPRMC
        if (strcmp(str[0], "$GPRMC") == 0)
        {
            coord.utc       = str[1];
            coord.lat       = str[3];
            coord.lat_dir   = str[4];
            coord.lon       = str[5];
            coord.lon_dir   = str[6];
            coord.speed_kn  = str[7];

            coord.heading   = headingPrev;
        }
        else if(strcmp(str[0], "$GPHDT") == 0) 
            coord.heading = headingPrev = str[1]; 

        // Print out the updated contents of cood after every loop
        printf("UTC : %s, \tLONG : %s, \tLONG_DIR : %s, \tLAT : %s, \tLAT_DIR : %s, \tSPEED(Kn) : %s, \tHEADING : %s\n", 
            coord.utc, coord.lat, coord.lat_dir, coord.lon, coord.lon_dir, coord.speed_kn, headingPrev);
    }

Printout of Results

c pointers typedef
1个回答
1
投票

你有

char* headingPrev = NULL;
    uint8_t* str[8] = { NULL };

这里的headingPrev和str是指针,它们只能保存地址而不是实际的字符串(或char数组)。所以,当你尝试

coord.heading = headingPrev = str[1]; 

这个语句headingPrev只指向str [1]。这相当于#define headingPrev &str[1],这显然不是你的意图。你需要headingPrev来保存str [1]的值而不是它的地址。所以,你需要做的是为headingPrev分配内存。如果str [1]的大小不固定,你可以使用char HeadingPrev[20]或使用malloc / calloc进行动态内存分配。然后你必须使用strcpy()将str [1]复制到headingPrev。所以最终的代码是

 if (strcmp(str[0], "$GPRMC") == 0)
        {
            coord.utc       = str[1];
            coord.lat       = str[3];
            coord.lat_dir   = str[4];
            coord.lon       = str[5];
            coord.lon_dir   = str[6];
            coord.speed_kn  = str[7];

            coord.heading   = headingPrev; //<---- This would still work since headingPrev would be same as &headingPrev[0] even after allocating memory
        }
        else if(strcmp(str[0], "$GPHDT") == 0) 
        {
           strcpy(headingPrev, str[1]);
            coord.heading = headingPrev; 
        }

您也可以将coord.heading = headingPrev;放在if-else块之外,因为它出现在if和else块中。

© www.soinside.com 2019 - 2024. All rights reserved.