MOOC翁凯C语言课的题目,题目如下(太多字就直接截图啦)
唔,看完题目可以知道其实就是要求读入多行字符串,然后找出符合条件的字符串,从中抽取六位数的UTC时间,把它转化成北京时间输出。
我想的大致思路就是:外层循环读入字符串,一直到END,然后里面把读入的单行字符串进行条件判断(先是需要$GPRMC,然后校验值要正确),遇到符合条件的字符串提取UTC时间并且转化,直到最后读到END之后再输出(因为要求只输出最后符合条件的)。
代码如下,由于我是初学者,可能很多便捷的函数我都不知道,所以如果有不妥欢迎批评指正。大部分解释都在代码注释里啦。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void copy(char *a,char *b,int start,int end);/*函数作用:把数组b中的start至end号元素copy到数组a中。(因为我对字符串函数不太了解,所以用自己写的)*/
void transform(int *h,int *m,int *s,int );/*把的6位数int的UTC时间转化成hms的北京时间*/
int main(void)
{
char ch[100]; /*放置读入的单行字符串*/
int ret,h,m,s; /*ret用来存储最后得到的六位UTC时间,hms就是结果的时分秒*/
scanf("%s",ch);
while (strcmp(ch,"END")) /*ch不等于END时进入循环体*/
{
char type[10]; /*用来储存GPS语句格式*/
copy(type,ch,0,5); /*从读取到的字符串中提取GPS语句格式*/
if (!strcmp(type,"$GPRMC") )/*type是$GPRMC时进入*/
{
int i,test; /*test用来存储读取到的字符串的异或运算值*/
test=ch[1]; /*先让它等于$后的第一个字符*/
for (i=2;ch[i]!='*';i++) /*循环计算$和*之间的字符串的异或运算值*/
{
test=test^ch[i];
}
test%=65530; /*得到读取字符串的理论校验值的十进制*/
char xtest[10]={0}; /*用来存放test的十六进制形式*/
sprintf(xtest,"%X",test); /*把test的十六进制形式放入xtest*/
char check[10]={0}; /*用于存储实际校验值*/
copy(check,ch,i+1,i+2); /*从字符串提取校验值*/
if (!strcmp(xtest,check)) /*比较理论校验值和实际校验值*/
{
char utc[10]; /*用于存储UTC时间*/
copy(utc,ch,7,12); /*从字符串提取UTC时间*/
ret=atoi(utc); /*把字符串转化为int*/
}
}
scanf("%s", ch);
}
transform(&h,&m,&s,ret); /*把六位数UTC时间转化为北京时间hms*/
printf("%02d:%02d:%02d", h, m, s); /*输出所得北京时间*/
return 0;
}
void copy(char *a,char *b,int start,int end)
{
int i;
for (i=start;i<=end;i++) /*把字符串b中的start到end号元素复制到a*/
{
*(a++)=*(b+i);
}
*a='\0'; /*数组a加上结尾的\0才是字符串*/
}
void transform(int *h,int *m,int *s,int ret)
{
ret/=1;
*s=ret%100;
ret/=100;
*m=ret%100;
*h=ret/100;
*h+=8; /*北京时间是UTC+8*/
if (*h>=24) *h-=24;
}
唔,基本上就是酱紫啦,大部分代码解析标注在代码里啦,如果有不懂的可以问我,如果代码有不妥的地方欢迎批评指正。