通过sscanf处理GPS信息

C语言提供了scanf通过IO格式化输入字符串,同样也提供了sscanf可以处理字符串,用于提取字符串中的有用信息。

之前在处理字符串的时候都是一个个字符遍历,如果要取中间的数值,还得把字符转为数字,然后做乘法加法,很是麻烦。

用sscanf可以将原来几十行的代码简化到一两行,见以下程序。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef	unsigned int			UINT32;
typedef	unsigned long long		UINT64;
typedef	UINT32					BOOL;
#define	TRUE					1
#define	FALSE					0

/* 日期时间结构体 8 bytes */
#pragma pack(1) 
typedef union _ZGDateTime
{
	UINT64 Ticks;

	struct  _tm
	{
		UINT32	US			: 12;	
		UINT32	MS			: 12;
		UINT32	Second		: 8;


		UINT32	Minute		: 6;
		UINT32	Hour		: 5;
		UINT32	Day			: 5;
		UINT32	Month		: 4;
		UINT32	Year		: 12;	
	}tm;
}ZGDateTime;

/* 定义GPS信息结构体 */
typedef struct _GPS_INFO_STRU
{
	ZGDateTime	dt;
	char		status;				// 状态A-有效,V为非有效接收警告,即当前天线视野上方的卫星个数少于3颗。
	float		latitude_value;		// 纬度值
	char		latitude;			// 纬度为N南纬或S北纬
	float 		longtitude_value;	// 经度值
    char 		longtitude;			// 经度标明东西半球,E为东半球、W为西半球
	float 		speed;				// 速度
    float 		azimuth_angle;		// 方位角
}GPS_INFO;


/*获取GPS信息,只处理$GPRMC*/
BOOL GetGpsInfo(const char *pStr, GPS_INFO *pGpsInfo)
{
	BOOL bl;
	int i;
	int year,month,day,hour,minute,second,ms;

	ZGDateTime	*dt;
	dt = &pGpsInfo->dt;


	
	memset(pGpsInfo, 0, sizeof(GPS_INFO));
	i = sscanf(pStr, "$GPRMC,%2d%2d%2d.%d\
			  %*[^VAva]%c,\
			  %f%*[^SNsn]%c,\
			  %f%*[^EWew]%c,\
			  %f,%f,\
			  %2d%2d%2d",  
			  &hour, &minute, &second, &ms,
			  &pGpsInfo->status, &pGpsInfo->latitude_value, &pGpsInfo->latitude,
			  &pGpsInfo->longtitude_value, &pGpsInfo->longtitude,
			  &pGpsInfo->speed, &pGpsInfo->azimuth_angle,
			  &day, &month, &year
			  );
	if(i >= 14 && (pGpsInfo->status == 'A' || pGpsInfo->status == 'a'))
	{
		dt->tm.Year = 2000+year;
		dt->tm.Month = month;
		dt->tm.Day = day;
		dt->tm.Hour = hour;
		dt->tm.Minute = minute;
		dt->tm.Second = second;
		dt->tm.MS = ms;
		dt->tm.US = 0;
		
		bl = TRUE;
	}
	else
	{
		bl = FALSE;
	}
	


	return bl;
}


int main()
{
	const char TestGpsText[]={"$GPRMC,024813.640,a,3158.4608,N,11848.3737,E,10.05,324.27,150706,,,A*50"};
	GPS_INFO	gpsInfo;
	GPS_INFO	*pGpsInfo;
	ZGDateTime	*dt;
	BOOL		bl;

	
	pGpsInfo = &gpsInfo;
	dt = &pGpsInfo->dt;
	bl = GetGpsInfo(TestGpsText, pGpsInfo);
	if(bl == TRUE)
	{
		printf( "%s %s\r\n", __DATE__, __TIME__);
		printf( "GPS信息:\r\n");
		printf( "时  间:%04d-%02d-%02d %02d:%02d:%02d %03d.%03d\r\n",
				   dt->tm.Year, dt->tm.Month, dt->tm.Day,
				   dt->tm.Hour, dt->tm.Minute, dt->tm.Second,
				   dt->tm.MS, dt->tm.US);
		printf( "状  态:%s\r\n", pGpsInfo->status == 'A' ? "有效" : "无效");
		printf( "经  度:%s%0.4f度\r\n", pGpsInfo->longtitude == 'E'? "东经" : "西经", pGpsInfo->longtitude_value);
		printf( "纬  度:%s%0.4f度\r\n", pGpsInfo->latitude == 'N'? "北纬" : "南纬", pGpsInfo->latitude_value);
		printf( "速  度:%.3f\r\n", pGpsInfo->speed);
		printf( "方位角:%.3f\r\n\r\n", pGpsInfo->azimuth_angle);
	}
	else
	{
		printf( "GPS数据无效\r\n");
	}
	system("pause");
}


  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
sscanf函数是一个在C语言中常用的函数,用于将字符流中的数据按照指定格式进行分割和处理。在给定的字符流中,sscanf函数可以通过指定的格式字符串,将特定的数据提取出来,并存储到对应的变量中。 关于sscanf函数的使用,我找到了两个例子来帮助解释。引用中的例子展示了如何使用sscanf函数来提取一个句子中的字符串和整数。通过指定格式字符串"%s %*s %d",sscanf函数会将句子中的第一个字符串和第三个整数提取出来并存储到相应的变量中。 另一个例子在引用中展示了更复杂的用法。通过指定格式字符串"%[^','],%[^','],%[^','],%s",sscanf函数可以将一个包含多个字段的字符串分割成多个部分,并将这些部分存储到对应的变量中。这个例子展示了如何从一个包含字段的字符串中提取字符串、浮点数和整数。 通过这些例子,我们可以看到sscanf函数的灵活性。通过不同的格式字符串,我们可以根据需要将字符流中的数据进行提取和处理。对于更详细的sscanf函数用法,可以参考引用中提供的链接。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [GPS项目实战系列之:再谈一次GPS数据解析](https://blog.csdn.net/wangwenxue1989/article/details/104710228)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值