色yeye在线视频观看_亚洲人亚洲精品成人网站_一级毛片免费播放_91精品一区二区中文字幕_一区二区三区日本视频_成人性生交大免费看

Hi,歡迎來到嵌入式培訓高端品牌 - 華清遠見教育科技集團<北京總部官網>,專注嵌入式工程師培養15年!
當前位置: > 華清遠見教育科技集團 > 嵌入式學習 > 講師博文 > 利用strstr和sscanf解析GPS信息
利用strstr和sscanf解析GPS信息
時間:2016-12-30作者:華清遠見

考察C程序員是否合格的一個重要標準就是看他操作字符串的能力,一個合格的C程序員應該可以熟練的對字符串進行拆分、組合、格式轉換以及搜索定位,從一堆數據中提取出有效信息。

比如說我們要做一個GPS導航的項目,需要讀取GPS模塊以ASCII碼的形式發送過來的數據,然后對這些數據進行處理,提取我們需要的信息。這就涉及到很多操作字符串的問題。下面就以此為例,利用strstr函數和sscanf函數解析GPS數據。

GPS輸出的數據格式如下:
$GPGGA,121252.000,3937.3032,N,11611.6046,E,1,05,2.0,45.9,M,-5.7,M,,0000*77 
$GPRMC,121252.000,A,3958.3032,N,11629.6046,E,15.15,359.95,070306,,,A*54 
$GPVTG,359.95,T,,M,15.15,N,28.0,K,A*04 
$GPGGA,121253.000,3937.3090,N,11611.6057,E,1,06,1.2,44.6,M,-5.7,M,,0000*72 
$GPGSA,A,3,14,15,05,22,18,26,,,,,,,2.1,1.2,1.7*3D 
$GPGSV,3,1,10,18,84,067,23,09,67,067,27,22,49,312,28,15,47,231,30*70 
$GPGSV,3,2,10,21,32,199,23,14,25,272,24,05,21,140,32,26,14,070,20*7E 
$GPGSV,3,3,10,29,07,074,,30,07,163,28*7D

可以看到,GPS模塊發送過來的原始數據有很多,但是通常我們只需要其中的一部分信息就夠用了,比如對于導航的功能,我們只需要以$GPRMC開頭,以換行符結束的一行信息就夠了。即:
$GPRMC,121252.000,A,3958.3032,N,11629.6046,E,15.15,359.95,070306,,,A*54

因此我們需要做的就是從讀取的數據中截取以$GPRMC開頭的一行信息,然后從中解析出經緯度、日期時間等有效信息即可。

假設從串口讀取的數據存放在一個字符串指針char *raw_buf指向的內存單元里,首先我們通過ANSI C提供的strstr()函數找到以$GPRMC開頭以換行符’\n’結束的字符串:
/* find "$GPRMC" from raw_buf */
if ((wellhandled_string = strstr(raw_buf, “$GPRMC”)) != NULL)
{
        for (i=0; i<strlen(wellhandled_string); i++)
        {
                if (wellhandled_string[i] == '\n')
                {
                        wellhandled_string[i] = '\0'; //replace ‘\n’ with null
                }
        } 
}
strstr()函數的原型是這樣聲明的:
char *strstr(const char *haystack, const char *needle);

strstr()函數可以在字符串haystack中搜索字符串needle第一次出現的位置,并且返回指向字符串needle首地址的指針,如果沒有搜索到則返回NULL。因此上面的代碼為我們在讀取的原始數據raw_buf里搜索$GPRMC第一次出現的位置,并將返回的指針賦給wellhandled_string,這樣如果搜索成功,則wellhandled_string就會指向以$GPRMC開始的字符串,接下來通過一個for循環找到換行符’\n’,將其替換為’\0’,即字符串結束符。這樣就得到了一個指向有效數據的字符串指針wellhandled_string。

然后要做的工作就是從wellhandled_string中提取出經緯度、日期時間等信息。這個工作就可以交給強大的sscanf函數來實現。sscanf函數的原型如下:
int sscanf(const char *str, const char *format, ...);

我們都比較熟悉scanf這個函數,scanf可以從標準輸入流讀取與指定格式相符的數據。sscanf則是從const char *str中讀取。它的強大之處在于可以方便地從字符串中取出整數、浮點數和字符串等各種類型的數據,而且它還具有類似于正則表達式的匹配功能,sscanf默認是以空格分隔字符串的,如果不是以空格來分割的話,就可以使用%[ ]來指定分割的條件。如%[a-z]表示讀取a到z的所有字符,%[^a-z]表示過濾a-z之間的所有字符,即只要遇到a到z之間的任意字符,轉換立刻停止。比如:
sscanf(“abcdefABCDEF”, “%[^A-Z]”, str);
printf(“%s\n”, str);
result is: abcdef
%[^A-Z]這樣的匹配格式為我們取遇到大寫字母為止的字符串。利用這種匹配方式,我們就可以靈活的操作字符串,得到我們想要的結果。

現在我們需要從下面的字符串中提取有效信息:
$GPRMC,121252.000,A,3958.3032,N,11629.6046,E,15.15,359.95,070306,,,A*54

GPRMC每個字段的含義如下:
$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>*hh<CR><LF> 
<1> UTC時間,hhmmss(時分秒)格式 
<2> 定位狀態,A=有效定位,V=無效定位 
<3> 緯度ddmm.mmmm(度分)格式(前面的0也將被傳輸) 
<4> 緯度半球N(北半球)或S(南半球) 
<5> 經度dddmm.mmmm(度分)格式(前面的0也將被傳輸) 
<6> 經度半球E(東經)或W(西經) 
<7> 地面速率(000.0~999.9節,前面的0也將被傳輸) 
<8> 地面航向(000.0~359.9度,以真北為參考基準,前面的0也將被傳輸) 
<9> UTC日期,ddmmyy(日月年)格式 
<10> 磁偏角(000.0~180.0度,前面的0也將被傳輸) 
<11> 磁偏角方向,E(東)或W(西) 
<12> 模式指示(僅NMEA0183 3.00版本輸出,A=自主定位,D=差分,E=估算,N=數據無效)

我們提取1~9九條信息。用一個結構體存放這些信息:
typedef struct gps_info
{
        char utc_time[BUF_SIZE];
        char status;
        float latitude_value;
        char latitude;
        float longtitude_value;
        char longtitude;
        float speed;
        float azimuth_angle;
        char utc_data[BUF_SIZE];
}GPS_INFO;

因為每一個字段之間都是以逗號間隔開的,所以我們可以利用%[^,]來分割字符串,這樣用sscanf函數就可以實現對有效信息的提取:
sscanf(wellhandled_string,"$GPRMC,%[^,],%c,%f,%c,%f,%c,%f,%f,%[^,]", 
            rmc_info->utc_time,\
            &(rmc_info->status),&(rmc_info->latitude_value),&(rmc_info->latitude),\
            &(rmc_info->longtitude_value),&(rmc_info->longtitude),&(rmc_info->speed),\
            &(rmc_info->azimuth_angle),\
            rmc_info->utc_data );
這個函數執行后,打印出的保存在struct gps_info結構體里的信息如下所示:
utc_time: 024813.640
status: A
latitude: N latitude value: 3158.460693
longtitude: E longtitude value: 11848.374023
speed: 10.050000
azimuth_angle: 324.269989
utc_data: 150706

可見,利用好sscanf函數,可以讓我們可以很高效的處理字符串。 

發表評論
評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
前台专线:010-82525158 企业培训洽谈专线:010-82525379 院校合作洽谈专线:010-82525379 Copyright © 2004-2018 北京华清远见科技集团有限公司 版权所有 ,京ICP备16055225号,京公海网安备11010802025203号
主站蜘蛛池模板: 亚洲 欧美 国产 日韩 精品 | 真人视频一级毛片 | 妺妺窝人体色www美国 | 中文字幕线观看 | 在线观看免费人成视频色9 久久青草国产免费频观 | 欧美无砖专区一中文字 | 成人午夜精品久久久久久久网站 | 青青草在久久免费久久免费 | ASS新版ASS毛茸茸PICS | 免费观看国产女人高潮视频 | 国产亚洲综合一区二区三区 | 顶级丰满少妇自慰到喷水 | 亚洲日韩精品国产一区二区三区 | 精品国产一区二区三区四区色欲 | 四虎影视免费观看高清视频 | 超清无码无卡中文字幕 | 高潮A片揉搓乳尖乱颤视频 91官网在线 | 精品国产国语对白久久免费 | 亚洲中文字幕无码MV | 三年片免费观看影视大全视频 | 国产免费拔擦拔擦8X高清在线 | 猫咪成人最新地域网 | 欧美老熟妇com | 亚洲极美女高清视频 | 中文字幕在线免费观看 | 亚洲AV色香蕉一区二区 | 欧美性生交片4 | 国产人妻人伦精品无码.麻豆 | 西西人体大胆扒开下部337卩 | 亚洲熟妇国产熟妇肥婆 | 四虎成人精品无码 | 国产又粗又黄又爽的A片精华液 | 朋友的丰满人妻中文字幕 | 真人一级毛片免费完整视频 | 懂色av中文在线 | 成人日韩熟女高清视频一区 | 三级网站久久 | 亚洲AV成人无码精品综合网站 | 7777久久 | 无码专区亚洲制服丝袜 | 最近的中文字幕在线mv视频 |