C语言mooc小程序(3)
来源:互联网 发布:电话座机迁走了没网络 编辑:程序博客网 时间:2024/05/17 04:23
最近学了,指针,字符串,了解不少新函数.
strcat;将一个字符串复制到另一个字符串后;
基本用法:strcat(a,b)
strcat(a,b+x)将b从x开始的字符串复制到a后.(个人尝试a+x但无效)
然而strcat b+x的方式显得繁琐,这时我们需要使用strncat,它把一个字符串所指字符串的前n个字符添加到另一个字符串结尾处
用法为strncat(a,b,x)
strcpy
把1所指由NULL结束的字符串复制到2所指的数组中
用法为strcpy(a+x,b+x) x代表从字符的第x个元素开始复制.
但strcpy极易造成内存泄漏,我们需要使用strncpy
用法为strncpy(a,b,x)把b所指向的字符串中以b地址开始的前x个字节复制到a所指的数组中.
注意:如果b指向的数组是一个比x短的字符串,则在a定义的数组后面补空字符,直到写入了x个字符.
但要注意的是,strcpy不会拷贝/0字符,所以,在初始元素内一定要加0.
否则输出乱码(亲身实践)
接下来还有strcmp 用来判断两字符是否相等
i=strcmp(字符串,字符串);
其中,字符串1、字符串2均可为字符串常量或变量;i 是用于存放比较结果的整型变量。比较结果是这样规定的:
①字符串1小于字符串2,strcmp函数返回一个负值;
②字符串1等于字符串2,strcmp函数返回零;
③字符串1大于字符串2,strcmp函数返回一个正值
然后做完两道实践题
你的程序要读入一行文本,其中以空格分隔为若干个单词,以‘.’结束。你要输出这行文本中每个单词的长度。这里的单词与语言无关,可以包括各种符号,比如“it’s”算一个单词,长度为4。注意,行中可能出现连续的空格。
输入格式: 输入在一行中给出一行文本,以‘.’结束,结尾的句号不能计算在最后一个单词的长度内。
输出格式:
在一行中输出这行文本对应的单词的长度,每个长度之间以空格隔开,行末没有最后的空格。
#include<stdio.h>#include<stdlib.h> int main() { int sign=' '; int flag=0,len=0; char c; while((c=getchar())!='.')//判断是否结束 { if(c!=' ') len++; else if(len!=0) { if(flag!=0) {putchar(sign);}//判断何时输出空格 flag=1; printf("%d",len); len=0; } else { continue; } } if(flag==1&&len!=0) putchar(sign); if(len); printf("%d",len);return 0; }
这题除了处理空格比较麻烦外,其余挺简单.
但下一题GPS处理很麻烦.
在此之前,先介绍一种函数sscanf
sscanf()函数用于从字符串中读取指定格式的数据,其原型如下:
int sscanf (char str, char format [, argument, …]);
【参数】参数str为要读取数据的字符串;format为用户指定的格式;argument为变量,用来保存读取到的数据。
【实例】从指定的字符串中读取整数和小写字母。
int main(void)
{
char str[100] =”123568qwerSDDAE”;
char lowercase[100];
int num;
sscanf(str,”%d %[a-z]”, &num, lowercase);
printf(“The number is: %d.\n”, num);
printf(“The lowercase is: %s.”, lowercase);
return 0;
}
我们可以利用这种函数提取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 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
表示数据的结束。
你的程序要从中找出
#include <stdio.h>#include <string.h>int verify(char a[]){ int sum=a[1],i,checkSum=0; for(i=2; a[i]!='*'; i++) { sum=sum^a[i]; } sum=sum%65536; sscanf(&a[i+1],"%2x",&checkSum); return sum==checkSum;}int main(int argc, char **argv){ char a[80],position; int hour=0,minute=0,second=0; double times=0; while(scanf("%s",a),strcmp(a,"END")!=0) { if(sscanf(a,"$GPRMC,%lf,%c,",×,&position)!=2 || position!='A' || !verify(a)) //如不满足条件,直接本次循环 { continue; } //将时间提取出时分秒 hour=((int)times/10000+8)%24; minute=(int)times/100%100; second=(int)times%100; printf("%02d:%02d:%02d",hour,minute,second); }//这样改可能不符合题目要求 但可以循环使用 return 0;}