当前位置:首页 > 工业控制 > 电子设计自动化
[导读]作者:杨硕,华清远见嵌入式学院讲师。 考察C程序员是否合格的一个重要标准就是看他操作字符串的能力,一个合格的C程序员应该可以熟练的对字符串进行拆分、组合、格式转换以及搜索定位,从一堆数据中提取出有效信息。

作者:杨硕,华清远见嵌入式学院讲师。

考察C程序员是否合格的一个重要标准就是看他操作字符串的能力,一个合格的C程序员应该可以熟练的对字符串进行拆分、组合、格式转换以及搜索定位,从一堆数据中提取出有效信息。

比如说我们要做一个GPS导航的项目,需要读取GPS模块以ASCII码的形式发送过来的数据,然后对这些数据进行处理,提取我们需要的信息。这就涉及到很多操作字符串的问题。下面就以此为例,利用strstr函数和sscanf函数解析GPS数据。

GPS输出的数据格式如下:

$GPGGA,121252.000,3937.3032,N,11611.*6,E,1,05,2.0,45.9,M,-5.7,M,,0000*77

$GPRMC,121252.000,A,3958.3032,N,11629.*6,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.*6,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] = ''; //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’,将其替换为’’,即字符串结束符。这样就得到了一个指向有效数据的字符串指针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(“%sn”, str);

result is: abcdef

%[^A-Z]这样的匹配格式为我们取遇到大写字母为止的字符串。利用这种匹配方式,我们就可以灵活的操作字符串,得到我们想要的结果。

现在我们需要从下面的字符串中提取有效信息:

$GPRMC,121252.000,A,3958.3032,N,11629.*6,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函数,可以让我们可以很高效的处理字符串。

“本文由华清远见http://www.embedu.org/index.htm提供”



来源:华清远见0次

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

华为鸿蒙系统作为一款全新的操作系统,自发布以来就备受关注。它不仅具备了安卓系统的所有基础功能,还增加了一些新的特色功能,为用户带来了全新的使用体验。本文将对华为鸿蒙系统的功能进行详细介绍。

关键字: 华为 鸿蒙系统 信息

随着信息时代的到来,数据成为了我们生活和工作中不可或缺的一部分。然而,海量的数据对我们来说往往难以理解和利用。这时,数据可视化技术的出现为我们提供了一种直观、有效的方式来展示和解读数据。本文将探讨数据可视化的作用以及其在...

关键字: 数据 信息 可视化

集成电路是指采用一定的工艺,把一个电路中所需的三极管、二极管、电阻、电容、电感等元器件及导线互连在一起,制作在一小块或几小块陶瓷、玻璃或半导体晶片上,然后封装在一起,成为一个能够实现一定电路功能的微型电子器件或部件。因此...

关键字: 集成电路 半导体 信息

自从技术出现以来,对技术的道德恐慌就一直是人类体验的一部分。而人类科技所带来的信息共享,正有逐步让人类打消对隐私的顾虑,习惯透明化生存,以及将人体作为物联网终端一部分的趋势。

关键字: 技术 物联网 信息

信息技术整体架构都由美国技术打造,哪里有后门,什么地方适合监听,美国人最清楚。8月5日,美国国务卿蓬佩奥在记者会上宣布美国将推行“干净网络”(Clean Network)行动,计划通过设立从电缆、网络路径到云端、运营商与...

关键字: 信息 技术 网络领域

探索科技(techsugar)呼吁,业内有决策权的关键人士从正面引导行业健康发展,必须要看到我国信息产业的安危系于半导体产业,不能只耽于市值幻想,或虚名(实利)——口口声声称国产替代,却从来没有真正产业化,也没有想过产业...

关键字: 探索科技 半导体 信息

两者都是嘴皮子一流的人,一个春风得意筹备上市,一个创业似乎有点倒霉,如果让罗振宇去当锤子科技的老大,能让其像罗辑思维一样,准上市吗?15日晚间,北京证监局官网更新了一则辅导报告显示,北京思维造物信息科技股份有限公司(下称...

关键字: 锤子科技 上市 信息

外界称为“打脸美国政治的北大教授”张海霞认为:“现在全球其他国家的芯片公司都在减少,只有中国有1600家芯片设计公司,而且还在增加。美国芯片工程师一般都是五六十岁,中国基本都是二三十岁,所以未来一定在中国。”

关键字: 信息 芯片 工程师

这场电子展似乎可以看作是成都电子信息产业的缩影。成都世纪城新国际会展中心西南角的台阶上,一头发花白老头拉响二胡,声音不算悠扬,像被昨日大雨冲哑了音调,同时被冲淡的还有空气中弥漫的火锅味。一时间,弦急声响,未干的水潭颤出波...

关键字: 电子展 产业 信息

2018年4月9日,在第六届中国电子信息博览会(CITE 2018)开幕式上,工业和信息化部部长苗圩发言时表示,中国电子信息产业保持快速发展的良好态势,2017年规模以上电子信息制造业收入超过13万亿元,软件信息技术服务...

关键字: 电子 信息 产业
关闭
关闭