C语言:关于GPS数据处理
各位大佬帮忙瞅瞅,才输入完程序就崩溃了!!!#include <stdio.h>
#include <string.h>
int isJYZ(int n); //判断校验是否正确
void BJT(int UTC); //将UTC时间换成北京时间
int main()
{
char s,s1,a,b;
//scanf("%s\n",&s);
//strcpy(s1,s);
int i1,i2 = 0,sum = 0;
int length1,length2;
//length1 = sizeof(s);
length1 = 0;
do{
scanf("%s",&s);
strcat(s1,s);
length1 += sizeof(s);
}while(strcmp(s,'END') != 0);
while(1){
strrchr(a,strrchr(s1,'));
length2 = sizeof(a);
sum += length2;
for( i1=0 ; i1< length2 ; i1++ ){
if(i2 < 16){
b = a;
}else{
if(i1 >= length2-2) b = a;
}
if(a =','){
i2++;
}
}
if(b=='A' && isJYZ(b)){
BJT(b);
break;
}
for( i1=0 ; i1<length1-sum ; i1++ ){
s1 = s;
}
}
return 0;
}
int isJYZ(int n)
{
int i = 0; //校验不正确
int a,b;
a = b/10;
int y = 1;
while(a < b%10){
y ^= a;
a++;
}
if(y%65536 == n){
i = 1; //校验正确
}
return i;
}
void BJT(int UTC){
int a1,a2,b,c;
a1 = UTC/10000;
b = UTC%10000/100;
c = UTC%10000%100;
if(a1 >= 1 && a1 <= 16){
a2 = a1 + 8;
}else{
a2 = a1 + 8 - 24;
}
if(a2 < 10){
printf("0%d",a2);
}else{
printf("%d",a2);
}
if(b < 10){
printf("0%d",b);
}else{
printf("%d",b);
}
if(c < 10){
printf("0%d",c);
}else{
printf("%d",c);
}
} 本帖最后由 超凡天赐 于 2017-5-7 20:20 编辑
#include <stdio.h>
#include <string.h>
int isJYZ(int n); //判断校验是否正确
void BJT(int UTC); //将UTC时间换成北京时间
void BJT(int UTC)
{
int a1,a2,b,c;
a1 = UTC/10000;
b = UTC%10000/100;
c = UTC%10000%100;
if(a1 >= 1 && a1 <= 16)
{
a2 = a1 + 8;
}
else
{
a2 = a1 + 8 - 24;
}
if(a2 < 10)
{
printf("0%d",a2);
}
else
{
printf("%d",a2);
}
if(b < 10)
{
printf("0%d",b);
}
else
{
printf("%d",b);
}
if(c < 10)
{
printf("0%d",c);
}
else
{
printf("%d",c);
}
}
int isJYZ(int n)
{
int i = 0; //校验不正确
int a,b = 0;
a = b/10;
int y = 1;
while(a < b%10)
{
y ^= a;
a++;
}
if(y%65536 == n)
{
i = 1; //校验正确
}
return i;
}
int main()
{
char s,s1,a,b;
//scanf("%s\n",s);
//strcpy(s1,s);
int i1,i2 = 0,sum = 0;
int length1,length2;
//length1 = sizeof(s);
length1 = 0;
do
{
scanf("%s",s);
strcat(s1,s);
length1 += sizeof(s);
}while(strcmp(s,"END") != 0);
while(1)
{
strrchr(a,*strrchr(s1,'a'));
length2 = sizeof(a);
sum += length2;
for( i1=0 ; i1< length2 ; i1++ )
{
if(i2 < 16)
{
b = a;
}
else
{
if(i1 >= length2-2) b = a;
}
if(a ==',')
{
i2++;
}
if(b=='A' && isJYZ(b))
{
BJT(b);
break;
}
for( i1=0 ; i1<length1-sum ; i1++ )
{
s1 = s;
}
}
}
return 0;
}
你的代码错的太多了,我找了一些错误。比如strchr()函数返回的是地址,应加上“*”。
scanf("%s",&s);
明显的错误应改为
scanf("%s",s);
等等一些错误,还有你的代码缩进非常糟糕。至于你有没有逻辑错误,你没给题目,我也不知道{:10_247:}
如果你发现上述代码不能运行成功,请讲清楚题目。代码也没有给输入提示。 {:10_266:}{:10_266:}{:10_266:}
题目内容:
NMEA-0183协议是为了在不同的GPS(全球定位系统)导航设备中建立统一的BTCM(海事无线电技术委员会)标准,由美国国家海洋电子协会(NMEA-The National Marine Electronics Associa-tion)制定的一套通讯协议。GPS接收机根据NMEA-0183协议的标准规范,将位置、速度等信息通过串口传送到PC机、PDA等设备。
NMEA-0183协议是GPS接收机应当遵守的标准协议,也是目前GPS接收机上使用最广泛的协议,大多数常见的GPS接收机、GPS数据处理软件、导航软件都遵守或者至少兼容这个协议。
NMEA-0183协议定义的语句非常多,但是常用的或者说兼容性最广的语句只有$GPGGA、$GPGSA、$GPGSV、$GPRMC、$GPVTG、$GPGLL等。
其中$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 Data(RMC)推荐最小定位信息
字段1:UTC时间,hhmmss.sss格式
字段2:状态,A=定位,V=未定位
字段3:纬度ddmm.mmmm,度分格式(前导位数不足则补0)
字段4:纬度N(北纬)或S(南纬)
字段5:经度dddmm.mmmm,度分格式(前导位数不足则补0)
字段6:经度E(东经)或W(西经)
字段7:速度,节,Knots
字段8:方位角,度
字段9:UTC日期,DDMMYY格式
字段10:磁偏角,(000 - 180)度(前导位数不足则补0)
字段11:磁偏角方向,E=东W=西
字段16:校验值
这里,“*”为校验和识别符,其后面的两位数为校验和,代表了“$”和“*”之间所有字符(不包括这两个字符)的异或值的十六进制值。上面这条例句的校验和是十六进制的50,也就是十进制的80。
提示:^运算符的作用是异或。将$和*之间所有的字符做^运算(第一个字符和第二个字符异或,结果再和第三个字符异或,依此类推)之后的值对65536取余后的结果,应该和*后面的两个十六进制数字的值相等,否则的话说明这条语句在传输中发生了错误。注意这个十六进制值中是会出现A-F的大写字母的。
现在,你的程序要读入一系列GPS输出,其中包含$GPRMC,也包含其他语句。在数据的最后,有一行单独的
END
表示数据的结束。
你的程序要从中找出$GPRMC语句,计算校验和,找出其中校验正确,并且字段2表示已定位的语句,从中计算出时间,换算成北京时间。一次数据中会包含多条$GPRMC语句,以最后一条语句得到的北京时间作为结果输出。
你的程序一定会读到一条有效的$GPRMC语句。
输入格式:
多条GPS语句,每条均以回车换行结束。最后一行是END三个大写字母。
输出格式:
6位数时间,表达为:
hh:mm:ss
其中,hh是两位数的小时,不足两位时前面补0;mm是两位数的分钟,不足两位时前面补0;ss是两位数的秒,不足两位时前面补0。
输入样例:
$GPRMC,024813.640,A,3158.4608,N,11848.3737,E,10.05,324.27,150706,,,A*50
END
输出样例:
10:48:13 超凡天赐 发表于 2017-5-7 20:18
你的代码错的太多了,我找了一些错误。比如strchr()函数返回的是地址,应加上“*”。
明显的错误应 ...
为什么 scanf("%s",s); 不用&??? 星若有泪 发表于 2017-5-7 20:51
为什么 scanf("%s",s); 不用&???
s本身表示的就是一个地址,是字符数组的首地址。&s是什么鬼{:10_277:} 星若有泪 发表于 2017-5-7 20:47
题目内容:
NMEA-0183协议是为了在不同的GPS(全球定位系统)导航设备中 ...
你这是竞赛题吧,这么长?{:10_247:} 超凡天赐 发表于 2017-5-7 22:12
你这是竞赛题吧,这么长?
我也不知道啊我在一个软件上学c人家给的题。。。所以说 我的程序问题很大吗
我主要就是想知道 关于字符串的输入问题 能不能讲讲先{:10_301:} 星若有泪 发表于 2017-5-7 22:30
我也不知道啊我在一个软件上学c人家给的题。。。所以说 我的程序问题很大吗
我主要就是想知道 关于 ...
s本身表示的就是一个地址,是字符数组的首地址。&s是什么鬼 本帖最后由 超凡天赐 于 2017-5-8 17:15 编辑
好吧,这一题我已经帮你做出来了,你写的代码我看不懂,{:10_266:} 所以我就自己写了一个。
其实这一题一点也不难,要放到竞赛,真是比送分还送分。就是题目有点长。这么长的题目,我们给它浓缩一下:
先验证‘$’和‘*’之间的字符累异或后的值(其实和累乘一个道理)是否等于‘*’后的两位数(这个数是16位进制的);
然后再将第一个逗号后的UCT时间转化为北京时间(其实就是将逗号后的两个数加上8,如果大于24就要剪去24;如果小于10,前面就要补零,比如02)。
当然了上面的只不过是我们的猜想,还要验证一下。写一个小代码
#include <stdio.h>
#include <string.h>
int main()
{
char a;
scanf("%s",a);
long length;
length=strlen(a);
int i;
int product=0;
for(i=0;i<length;i++)
product^=a;
int result;
result=product%65536;
printf("%x",result);
}//GPRMC,024813.640,A,3158.4608,N,11848.3737,E,10.05,324.27,150706,,,A
我们输入一下题目中所给的数据
GPRMC,024813.640,A,3158.4608,N,11848.3737,E,10.05,324.27,150706,,,A
输出的结果为
50
{:10_279:} 对了,好这下我们要用代码来描绘算法了。
#include <stdio.h>
#include <string.h>
int verification(char str[])
{
int a,b;
int location=0;
while(str!='*')
{
location++;
}
if(str>='A'&&str<='F')
a=str-'A'+10;
else
a=str-'0';
if(str>='A'&&str<='F')
b=str-'A'+10;
else
b=str-'0';
int proof_text_value;
proof_text_value=a*16+b;//proof_text_value转化为10进制数
int product=0,i;
for(i=1;i<=location-1;i++)
product^=str;
product=product%65536;//product为10进制数
if(product==proof_text_value)
return 1;
else
return 0;
}
void transfer_time(char str[])//只需要对location+1到location+2位数字进行转换
{
int a,b;
int location=0;
while(str!=',')
{
location++;
}
a=str-'0';
b=str-'0';
int UCT_time,Beijing_time;
UCT_time=a*10+b;
Beijing_time=UCT_time+8;
if(Beijing_time>=24)
printf("%d:%c%c:%c%c\n",Beijing_time-24,str,str,str,str);
else if(Beijing_time<10)
printf("0%d:%c%c:%c%c\n",Beijing_time,str,str,str,str);
else
printf("%d:%c%c:%c%c\n",Beijing_time,str,str,str,str);
}
int main()
{
char a;
char b="END";
int i=0,n;
do
{
scanf("%s",a);
i++;
}while(strcmp(a,b)!=0);
for(n=0;n<i-1;n++)
if(verification(a)==1)
transfer_time(a);
return 0;
}
我们下面要输入数据,老天保佑不要错{:10_254:}
$GPRMC,024813.640,A,3158.4608,N,11848.3737,E,10.05,324.27,150706,,,A*50
END
对了对了{:10_298:}
10:48:13
ok,但是我还要提醒你,{:10_266:} ,在竞赛中,那群变态会找一大些数据来测试,一个不通过抠分。超时也会扣分,甚至0分。所以这个代码有可能不会得100{:10_263:} 。
不过这个题目有一点我不明白,那就是我一开始认为这个字符数组长度是固定的。因为好像每一项都是固定的。不过后来我看到他的题目说长度是不固定的。所以一开始我的代码是{:10_319:}
#include <stdio.h>
#include <string.h>
int main()
{
char a;
scanf("%s",a);
long length;
length=strlen(a);
int i;
int product=0;
for(i=0;i<length;i++)
product^=a;
int result;
result=product%65536;
printf("%x",result);
}//GPRMC,024813.640,A,3158.4608,N,11848.3737,E,10.05,324.27,150706,,,A
//其实依据你这道题的意思,刚开始时,字符长度已经确定了,为71。
#include <stdio.h>
#include <string.h>
int verification(char str[])
{
int a,b;
if(str>='A'&&str<='F')
a=str-'A'+10;
else
a=str-'0';
if(str>='A'&&str<='F')
b=str-'A'+10;
else
b=str-'0';
int proof_text_value;
proof_text_value=a*16+b;//proof_text_value转化为10进制数
int product=0,i;
for(i=1;i<=67;i++)
product^=str;
product=product%65536;//product为10进制数
if(product==proof_text_value)
return 1;
else
return 0;
}
void transfer_time(char str[])//只需要对7到8位数字进行转换
{
int a,b;
a=str-'0';
b=str-'0';
int UCT_time,Beijing_time;
UCT_time=a*10+b;
Beijing_time=UCT_time+8;
if(Beijing_time>=24)
printf("%d:%c%c:%c%c\n",Beijing_time-24,str,str,str,str);
else if(Beijing_time<10)
printf("0%d:%c%c:%c%c\n",Beijing_time,str,str,str,str);
else
printf("%d:%c%c:%c%c\n",Beijing_time,str,str,str,str);
}
int main()
{
char a;
char b="END";
int i=0,n;
do
{
scanf("%s",a);
i++;
}while(strcmp(a,b)!=0);
for(n=0;n<i;n++)
if(verification(a)==1)
transfer_time(a);
return 0;
}
有点啰嗦,但我希望你能看完。{:10_267:} 超凡天赐 发表于 2017-5-8 17:12
好吧,这一题我已经帮你做出来了,你写的代码我看不懂, 所以我就自己写了一个。
其实这一题一 ...
为什么我答得这么详细,也不给采纳?{:10_292:}@人造人 看下学习学习
页:
[1]