我写了一个函数来解析一个NMEA语句,将参数存储在不同的数组中并写出它们的值。
首先我在控制台中运行它,一切都按预期工作。 main()中测试命令的功能如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//$GPSACP: 200949.000,4603.9172N,01429.5821E,1.0,337.8,3,53.82,0.36,0.19,231011,06
char *get_substring(size_t start, size_t stop, const char *src, char *dst, size_t size)
{
int count = stop - start;
if ( count >= --size )
{
count = size;
}
sprintf(dst, "%.*s", count, src + start);
return dst;
}
void get_separator_position(char *input_string, int *separators_array, int separators_count)
{
//10 separators
char *separator = ",";
char *current_string = input_string;
int current = 0;
char *found;
int pos;
int cur_pos = 0;
for(current = 0; current < separators_count; current++)
{
found = strstr(current_string, separator);
if(found != NULL)
{
pos = found - current_string;
cur_pos += pos;
separators_array[current] = cur_pos + current;
current_string = &input_string[cur_pos + 1 + current];
}
else
{
//printf("Not found!\n");
}
}
}
void parse_nmea_string(char *nmea_string, char *utc, char *latitude, char *longitude, char *hdop, char *altitude, char *fix, char *cog, char *spkm, char *spkn, char *date, char *nsat)
{
//10 separators "," in NMEA sentence
int separators_array[10];
get_separator_position(nmea_string, &separators_array[0], 10);
int length = strlen(nmea_string);
utc = get_substring(9, separators_array[0] + 1, nmea_string, utc, sizeof(char) * (separators_array[0] - 9 + 1));
latitude = get_substring(separators_array[0] + 1, separators_array[1], nmea_string, latitude, sizeof(char) * (separators_array[1] - separators_array[0]));
longitude = get_substring(separators_array[1] + 1, separators_array[2], nmea_string, longitude, sizeof(char) * (separators_array[2] - separators_array[1]));
hdop = get_substring(separators_array[2] + 1, separators_array[3], nmea_string, hdop, sizeof(char) * (separators_array[3] - separators_array[2]));
altitude = get_substring(separators_array[3] + 1, separators_array[4], nmea_string, altitude, sizeof(char) * (separators_array[4] - separators_array[3]));
fix = get_substring(separators_array[4] + 1, separators_array[5], nmea_string, fix, sizeof(char) * (separators_array[5] - separators_array[4]));
cog = get_substring(separators_array[5] + 1, separators_array[6], nmea_string, cog, sizeof(char) * (separators_array[6] - separators_array[5]));
spkm = get_substring(separators_array[6] + 1, separators_array[7], nmea_string, spkm, sizeof(char) * (separators_array[7] - separators_array[6]));
spkn = get_substring(separators_array[7] + 1, separators_array[8], nmea_string, spkn, sizeof(char) * (separators_array[8] - separators_array[7]));
date = get_substring(separators_array[8] + 1, separators_array[9], nmea_string, date, sizeof(char) * (separators_array[9] - separators_array[8]));
nsat = get_substring(separators_array[9] + 1, length, nmea_string, nsat, sizeof(char) * (length - separators_array[9]));
}
int main(int argc, char *argv[])
{
static const char text[] = "$GPSACP: 200949.000,4603.9172N,01429.5821E,1.0,337.8,3,53.82,0.36,0.19,231011,06";
char utc[20];
char latitude[30];
char longitude[20];
char hdop[20];
char altitude[20];
char fix[20];
char cog[20];
char spkm[20];
char spkn[20];
char date[20];
char nsat[20];
printf("Separator %d at position %d\n", pos, separators_array[pos]);
parse_nmea_string(text, utc, latitude, longitude, hdop, altitude, fix, cog, spkm, spkn, date, nsat);
printf("UTC: %s\n", utc);
system("PAUSE");
return 0;
}
此代码工作正常,测试输出
UTC: 200949.000
然后我尝试在微控制器项目中使用上述函数,并使用现有的debug_str()函数编写数组值,如下所示:
// Debug function prints string msg to UART1 (to PC)
void debug_str(const char* msg)
{
#ifdef debug
putchar1(0x24); //$
while(*msg)
{
putchar1(*msg++);
}
putchar1(0x0D); //Carriage Return
#endif
}
因此,将解析函数与现有代码相结合,我尝试按以下方式编写数组值:
char UTC[15];
char latitude[15];
char longitude[15];
char hdop[6];
char altitude[9];
char fix[5];
char cog[10];
char spkm[8];
char spkn[8];
char date[10];
char nsat[6];
static const char nmea_test[] = "$GPSACP: 200949.000,4603.9172N,01429.5821E,1.0,337.8,3,53.82,0.36,0.19,231011,06";
...
parse_nmea_string(nmea_test, UTC, latitude, longitude, hdop, altitude, fix, cog, spkm, spkn, date, nsat);
debug_str(latitude);
但这样输出不正确。
输出:
$*s
有没有人问题是什么以及如何正确地存储和写入从字符串nmea_test解析的参数?
谢谢!
答案 0 :(得分:0)
你应该理解C中数组和指针之间的区别。 阅读任何关于此的优秀C教科书。
您的get_substring
功能无法达到您的预期效果。它没有为其结果分配任何字符串。
您可以考虑在strdup
中使用get_substring
,并采用调用者应该free
结果的约定。
答案 1 :(得分:0)
现在它有效。函数get_substring和get_separator_positions必须通过以下方式进行修改:
char *get_substring(unsigned int start, unsigned int stop, const char *src, char *dst, unsigned int size)
{
int count = stop - start;
if ( count >= --size )
{
count = size;
}
// sprintf(dst, "%.*s", count, src + start); - this line was replaced by the following two lines (the microcontroller does not support strdup so strncpy had to be used)
strncpy(dst, &src[start], size);
dst[size] = '\n';
return dst;
}
//char input_string[] = "$GPSACP: 200949.000,4603.9172N,01429.5821E,1.0,337.8,3,53.82,0.36,0.19,231011,06";
void get_separator_position(char *input_string, int *separators_array, int separators_count)
{
//10 separators
char separator[] = ",";//char *separator = "," didn't work
char *current_string = input_string;
int current = 0;
char *found;
int pos;
int cur_pos = 0;
//char tmp_pos[10];
for(current = 0; current < separators_count; current++)
{
found = strstr(current_string, separator);
if(found != NULL)
{
debug_str("found!");
//debug_str(found);
pos = found - current_string;
// itoa(pos,tmp_pos);
// debug_str(tmp_pos);
cur_pos += pos;
separators_array[current] = cur_pos + current;
current_string = &input_string[cur_pos + 1 + current];
}
else
{
debug_str("Not found!");
}
}
}