[英]Parsing a NMEA String using strok in C
我正在嘗試使用帶有分隔符"," 的strtok 函數解析 GNRMC 字符串,當我注意到一些我沒有預料到的不同時,一切都很順利。 如果字符串包含連續的“,”,則 strtok 超調和打印功能錯位真實數據,我的目標是在連續的“,”之間沒有可用數據時打印數字0
我該怎么做。?
這是我的代碼
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char str[] = "$GPRMC,105954.000,A,3150.6731,N,11711.9399,E,0.00,96.10,250313,,,A*53";
char* Message_ID = strtok(str,",");
char* Time = strtok(NULL,",");
char* Data_Valid = strtok(NULL,",");
char* Raw_Latitude = strtok(NULL,",");
char* N_S = strtok(NULL,",");
char* Raw_Longitude = strtok(NULL,",");
char* E_W = strtok(NULL,",");
char* Speed = strtok(NULL,",");
char* COG = strtok(NULL,",");
char* Date = strtok(NULL,",");
char* Magnetic_Variation = strtok(NULL,",");
char* M_E_W = strtok(NULL,",");
char* Positioning_Mode = strtok(NULL,",");
double Latitude = atof(Raw_Latitude);
double Longitude = atof(Raw_Longitude);
printf("The Message ID is : %s\n", Message_ID);
printf("The Time is : %s\n", Time);
printf("The data valid is : %s\n", Data_Valid);
printf("The Latitude is : %f\n", Latitude);
printf("The N_S is : %s\n", N_S);
printf("The Longitude is : %f\n", Longitude);
printf("The E_W is : %s\n", E_W);
printf("The Speed is : %s\n", Speed);
printf("The COG is : %s\n", COG);
printf("The Date is : %s\n", Date);
printf("The Magnetic_Variation is : %s\n", Magnetic_Variation);
printf("The M_E_W is : %s\n", M_E_W);
printf("The Positioning_Mode is : %s\n", Positioning_Mode);
return 0;
}
如果您只檢測到一個特定字符(如','
),那么直接的方法是使用舊的strchr()
。
char str[] =
"$GPRMC,105954.000,A,3150.6731,N,11711.9399,E,0.00,96.10,250313,,,A*53";
char* message_id = str;
char* time = strchr(message_id, ','); *time = '\0'; ++time;
char* data_valid = strchr(time,","); *data_valid = '\0'; ++data_valid;
char* raw_latitude = strchr(data_valid,","); *raw_latitude = '\0'; ++raw_latitude;
...
一個棘手的宏可以簡化使用:
#define FIND_AND_NUL(s, p, c) ( \
(p) = strchr(s, c), \
*(p) = '\0', \
++(p), \
(p))
像這樣使用它:
char str[] =
"$GPRMC,105954.000,A,3150.6731,N,11711.9399,E,0.00,96.10,250313,,,A*53";
char* message_id = str;
char* time = FIND_AND_NUL(message_id, time, ',');
char* data_valid = FIND_AND_NUL(time, data_valid, ',');
char* raw_latitude = FIND_AND_NUL(data_valid, raw_latitude, ',');
...
我使用自己的 strtok 函數,該函數非常簡單,但與原始函數有兩個不同之處:(1) 分隔符只是單個字符而不是字符串 (2) 如果要解析的字符串有兩個連續的分隔符,則該函數返回一個空的非 -空標記“”。 這對於解析 NMEA 消息非常方便。
char *strtok_fr (char *s, char delim, char **save_ptr)
{
char *tail;
char c;
if (s == NULL) {
s = *save_ptr;
}
tail = s;
if ((c = *tail) == '\0') {
s = NULL;
}
else {
do {
if (c == delim) {
*tail++ = '\0';
break;
}
}while ((c = *++tail) != '\0');
}
*save_ptr = tail;
return s;
}
非遞歸版本:
char *strtok_f (char *s, char delim)
{
static char *save_ptr;
return strtok_fr (s, delim, &save_ptr);
}
所以,你的例子(注意','而不是“,”分隔符和strtok_f而不是strtok函數):
int main (int argc, char *argv[])
{
char str[] = "$GPRMC,105954.000,A,3150.6731,N,11711.9399,E,0.00,96.10,250313,,,A*53";
char* Message_ID = strtok_f(str,',');
char* Time = strtok_f(NULL,',');
char* Data_Valid = strtok_f(NULL,',');
char* Raw_Latitude = strtok_f(NULL,',');
char* N_S = strtok_f(NULL,',');
char* Raw_Longitude = strtok_f(NULL,',');
char* E_W = strtok_f(NULL,',');
char* Speed = strtok_f(NULL,',');
char* COG = strtok_f(NULL,',');
char* Date = strtok_f(NULL,',');
char* Magnetic_Variation = strtok_f(NULL,',');
char* M_E_W = strtok_f(NULL,',');
char* Positioning_Mode = strtok_f(NULL,',');
double Latitude = atof(Raw_Latitude);
double Longitude = atof(Raw_Longitude);
printf("The Message ID is : %s\n", Message_ID);
printf("The Time is : %s\n", Time);
printf("The data valid is : %s\n", Data_Valid);
printf("The Latitude is : %f\n", Latitude);
printf("The N_S is : %s\n", N_S);
printf("The Longitude is : %f\n", Longitude);
printf("The E_W is : %s\n", E_W);
printf("The Speed is : %s\n", Speed);
printf("The COG is : %s\n", COG);
printf("The Date is : %s\n", Date);
printf("The Magnetic_Variation is : %s\n", Magnetic_Variation);
printf("The M_E_W is : %s\n", M_E_W);
printf("The Positioning_Mode is : %s\n", Positioning_Mode);
return 0;
}
現在的結果:
消息 ID 是:$GPRMC
時間是:105954.000
有效數據為:A
緯度是:3150.673100
N_S 是:N
經度為:11711.939900
E_W 是:E
速度為:0.00
重心為:96.10
日期是:250313
Magnetic_Variation 是:
M_E_W 是:
Positioning_Mode 為:A*53
C:\\用戶\\froca\\桌面\\strtok>
請注意,“Magnetic Variation”和“M_E_W”現在是空標記。 這就是關鍵。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.