[英]String parsing, storing, and reading in 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解析出的參數並將其寫入輸出?
謝謝!
您應該了解C語言中數組與指針之間的區別。請閱讀有關此內容的所有優秀C教科書。
您的get_substring
函數不能滿足您的期望。 它不會為其結果分配任何字符串。
您可以考慮在get_substring
使用strdup
,並采用調用者應free
結果的約定。
現在可以了。 必須通過以下方式修改函數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!");
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.