qfedu-c-level/day12/homework/h9.c

119 lines
4.2 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
了解GPS相关知识
$GPRMC协议格式
  例:$GPRMC, 024813.640, A, 3158.4608, N, 11848.3737, E, 10.05, 324.27, 150706, , , A * 50
  字段0$GPRMC语句ID表明该语句为Recommended Minimum Specific GPS / TRANSIT DataRMC推荐最小定位信息
  字段1UTC时间hhmmss.sss格式(UTC时间是世界统一时间中国的时间是UTC + 8比如上面的时间是02 : 48 : 13而中国的时间是10 : 48 : 13)
  字段2状态A = 定位V = 未定位
  字段3纬度ddmm.mmmm度分格式前导位数不足则补0
  字段4纬度N北纬或S南纬
  字段5经度dddmm.mmmm度分格式前导位数不足则补0
  字段6经度E东经或W西经
  字段7速度Knots
  字段8方位角
  字段9UTC日期DDMMYY格式
  字段10磁偏角000 - 180前导位数不足则补0
  字段11磁偏角方向E = 东W = 西
  字段16校验值
【提示】利用strtok切割、sscanf或者strncpy、atoi、atof
*/
#include <stdio.h>
#include <string.h>
typedef struct
{
char time[10]; // UTC时间格式为hhmmss.sss
char status; // 状态A表示定位V表示未定位
double latitude; // 纬度格式为ddmm.mmmm
char latitude_dir; // 纬度半球N表示北半球S表示南半球
double longitude; // 经度格式为dddmm.mmmm
char longitude_dir; // 经度半球E表示东经W表示西经
double speed; // 速度,以节为单位
double course; // 方位角,以度为单位
char date[7]; // UTC日期格式为DDMMYY
double declination; // 磁偏角,以度为单位
char declination_dir; // 磁偏角方向E表示东偏W表示西偏
} gprmc_t;
int parse_gprmc(const char *str, gprmc_t *gprmc)
{
char *token;
int i = 0;
token = strtok((char *)str, ",");
while (token != NULL)
{
switch (i)
{
case 0:
if (strcmp(token, "$GPRMC") != 0)
{
return -1;
}
break;
case 1:
sscanf(token, "%2s", gprmc->time);
sscanf(token + 2, "%2lf%lf", &gprmc->time[2], &gprmc->time[4]);
sscanf(token + 4, "%lf", &gprmc->time[6]);
break;
case 2:
gprmc->status = *token;
break;
case 3:
sscanf(token, "%lf", &gprmc->latitude);
sscanf(token + 2, "%lf", &gprmc->latitude);
break;
case 4:
gprmc->latitude_dir = *token;
break;
case 5:
sscanf(token, "%lf", &gprmc->longitude);
sscanf(token + 3, "%lf", &gprmc->longitude);
break;
case 6:
gprmc->longitude_dir = *token;
break;
case 7:
sscanf(token, "%lf", &gprmc->speed);
break;
case 8:
sscanf(token, "%lf", &gprmc->course);
break;
case 9:
sscanf(token, "%2s", gprmc->date);
sscanf(token + 2, "%2lf%lf", &gprmc->date[2], &gprmc->date[4]);
sscanf(token + 4, "%lf", &gprmc->date[6]);
break;
case 10:
sscanf(token, "%lf", &gprmc->declination);
break;
case 11:
gprmc->declination_dir = *token;
break;
default:
break;
}
token = strtok(NULL, ",");
i++;
}
return 0;
}
int main()
{
const char *str = "$GPRMC,024813.640,A,3158.4608,N,11848.3737,E,10.05,324.27,150706,,,A*50";
gprmc_t gprmc;
if (parse_gprmc(str, &gprmc) == 0)
{
printf("UTC时间%s\n", gprmc.time);
printf("状态:%c\n", gprmc.status);
printf("纬度:%lf %c\n", gprmc.latitude, gprmc.latitude_dir);
printf("经度:%lf %c\n", gprmc.longitude, gprmc.longitude_dir);
printf("速度:%lf\n", gprmc.speed);
printf("方位角:%lf\n", gprmc.course);
printf("UTC日期%s\n", gprmc.date);
printf("磁偏角:%lf %c\n", gprmc.declination, gprmc.declination_dir);
}
return 0;
}