星若有泪 发表于 2017-5-7 19:46:22

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:18:01

本帖最后由 超凡天赐 于 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:}
如果你发现上述代码不能运行成功,请讲清楚题目。代码也没有给输入提示。

星若有泪 发表于 2017-5-7 20:47:04

{: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:51:11

超凡天赐 发表于 2017-5-7 20:18
你的代码错的太多了,我找了一些错误。比如strchr()函数返回的是地址,应加上“*”。

明显的错误应 ...

为什么 scanf("%s",s); 不用&???

超凡天赐 发表于 2017-5-7 22:11:40

星若有泪 发表于 2017-5-7 20:51
为什么 scanf("%s",s); 不用&???

s本身表示的就是一个地址,是字符数组的首地址。&s是什么鬼{:10_277:}

超凡天赐 发表于 2017-5-7 22:12:16

星若有泪 发表于 2017-5-7 20:47
题目内容:
NMEA-0183协议是为了在不同的GPS(全球定位系统)导航设备中 ...

你这是竞赛题吧,这么长?{:10_247:}

星若有泪 发表于 2017-5-7 22:30:02

超凡天赐 发表于 2017-5-7 22:12
你这是竞赛题吧,这么长?

我也不知道啊我在一个软件上学c人家给的题。。。所以说 我的程序问题很大吗
我主要就是想知道 关于字符串的输入问题 能不能讲讲先{:10_301:}

超凡天赐 发表于 2017-5-8 08:58:11

星若有泪 发表于 2017-5-7 22:30
我也不知道啊我在一个软件上学c人家给的题。。。所以说 我的程序问题很大吗
我主要就是想知道 关于 ...

s本身表示的就是一个地址,是字符数组的首地址。&s是什么鬼

超凡天赐 发表于 2017-5-8 17:12:57

本帖最后由 超凡天赐 于 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-11 14:42:07

超凡天赐 发表于 2017-5-8 17:12
好吧,这一题我已经帮你做出来了,你写的代码我看不懂, 所以我就自己写了一个。
其实这一题一 ...

为什么我答得这么详细,也不给采纳?{:10_292:}@人造人

xls6688 发表于 2017-5-11 15:00:34

看下学习学习
页: [1]
查看完整版本: C语言:关于GPS数据处理