C 中的字符串解析、存储和读取
我编写了一个函数来解析 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 解析的参数并将其写入输出吗?
谢谢你!
I wrote a functions to parse a NMEA sentence, store parameters in separate arrays and write their values.
First I ran it in console and everything worked as expected. The functions along the test commands in main() are the following:
#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;
}
This code works fine and the test output is
UTC: 200949.000
Then I tried to use the above function on the microcontroller project and write the array values using the existing debug_str() function which is the following:
// 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
}
So combining the parsing functions with existing code I tried to write the array values the following way:
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);
But this way the output was not correct.
Output:
$*s
Does anyone what the problem is and how to correctly store and write to the output the parameters which are parsed from the string nmea_test?
Thank you!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你应该了解 C 中数组和指针之间的区别。
阅读任何关于这方面的优秀 C 教科书。
您的
get_substring
函数未达到您的预期。它不会为其结果分配任何字符串。您可以考虑在
get_substring
中使用strdup
,并采用调用者应释放
结果的约定。You should understand the difference between arrays and pointers in C.
Read any good C textbook about this.
Your
get_substring
function don't do what you expect. It does not allocate any string for its result.You might consider using
strdup
insideget_substring
, and adopt the convention that the caller shouldfree
the result.现在可以了。函数 get_substring 和 get_separator_positions 必须按以下方式修改:
Now it works. Functions get_substring and get_separator_positions had to be modified the following way: