利用strstr和sscanf解析GPS信息

解析GPS信息:利用strstr和sscanf的高效字符串操作
本文介绍了如何使用C语言中的strstr和sscanf函数解析GPS数据,提取有效信息,如时间、定位状态、经纬度、速度等。通过结构体存储和sscanf函数分割字符串,实现对GPS输出数据的高效处理。

转自:http://www.cnblogs.com/shenlian/archive/2011/10/10/2205884.html


利用strstr和sscanf解析GPS信息

考察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,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>*hh

<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九条信息。

$GPRMC ,121252.000 ,A ,3958.3032 ,N ,11629.6046 ,E ,15.15 ,359.95 ,070306, , ,A*54

用一个结构体存放这些信息: 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函数,可以让我们可以很高效的处理字符串。



备注:

strstr:

包含文件:string.h
函数名: strstr   
函数原型:extern char *strstr(char *str1, char *str2);   
功能:找出str2字符串在str1字符串中第一次出现的位置(不包括str2的串结束符)。   
返回值:返回该位置的指针,如找不到,返回空指针。


sscanf:

sscanf() - 从一个字符串中读进与指定格式相符的数据.   
函数原型:   
int sscanf( const char *, const char *, ...);   
int sscanf(const char *buffer,const char *format,[argument ]...);   
buffer 存储的数据   
format 格式控制字符串   
argument 选择性设定字符串 
  
sscanf会从buffer里读进数据,依照argument的设定将数据写回。

strchr

原型:extern char *strchr(const char *s,char c);   
const char *strchr(const char* _Str,int _Val)   
char *strchr(char* _Str,int _Ch)   
头文件:#include <string.h>   
功能:查找字符串s中首次出现字符c的位置   
说明:返回首次出现c的位置的指针,如果s中不存在c则返回NULL。   
返回值:Returns the address of the first occurrence of the character in the string if successful, or NULL otherwise



评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值