即使 IF 语句为假,字符指针数组也会被覆盖
Character pointer array gets written over even when IF statement is false
我正在按指定的分隔符分解字符串,并尝试根据第一个字符串修改 typedef
结构。我意识到,当我逐步执行代码时,即使 if 语句为假,typedef
结构也会被覆盖。我希望它保留之前 for-loop 迭代的旧值,但它没有。
我也在考虑创建局部字符变量来保存 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);
}
你有
char* headingPrev = NULL;
uint8_t* str[8] = { NULL };
这里的 headingPrev 和 str 是指针,它们只能保存地址而不是实际的字符串(或字符数组)。
所以当你尝试
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 块中。
我正在按指定的分隔符分解字符串,并尝试根据第一个字符串修改 typedef
结构。我意识到,当我逐步执行代码时,即使 if 语句为假,typedef
结构也会被覆盖。我希望它保留之前 for-loop 迭代的旧值,但它没有。
我也在考虑创建局部字符变量来保存 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);
}
你有
char* headingPrev = NULL;
uint8_t* str[8] = { NULL };
这里的 headingPrev 和 str 是指针,它们只能保存地址而不是实际的字符串(或字符数组)。 所以当你尝试
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 块中。