关于字符串的一些操作
之前一直没有关注字符串的操作,以为嵌入式肯定用不到,这次播放器实验中用到了,需要在这里总结一下。
源文件放在strings.rar
1、字符串的赋值
C语言中,有两种方式可以存放字符串。字符数组和字符指针,见下面的程序。如果用数组的方式来存放,str0和str1是一种,把每个字符都分开写。str0有明确的数组长度,打印的时候,没有赋值的部分自动为0.而str1没有明确的长度,没有赋值的长度是不定的,而且打印出来,除了有效部分,还有打印中乱七八糟的东西。如果在str1的赋值末尾加上'\0',就能明确限定长度了。str2是字符数组的另一种方式,肯定首选这个了。
要注意的是,字符指针指向的是字符串常量,是不能修改的。而字符数组是可以修改的。
2、字符串的打印
可以直接用printf("%s")来打印,也可以用循环的方式,通过判断末尾来打印,见程序中str3的打印。str0/1/2能用循环打印吗?当然也是可以了,但是不能通过str0/1/2++的方式,因为str0/1/2是数组,是字符常量。而指针是可以自由移动的,想打印str3所指向的字符串,第五个字符后面的部分,直接用str3=str3+5,然后用printf函数打印出来即可。
3、字符串的长度
见程序中printf函数的打印值,长度都在注释中。
#include <stdio.h> #include <strings.h> int main(void) { //数组和指针两种定义 char str0[20]={'I','L','O','V','E','Y','O','U'}; char str1[]={'I','L','O','V','E','Y','O','U'}; //初始化的时候可以这样,不能用于赋值,注意这个终止的 char str2[]="ILOVEYOU"; //{"ILOVEYOU"} 一样 char *str3="ILOVEYOU"; printf("str0 is %s\n",str0); printf("str1 is %s\n",str1); //ILOVEYOU$@&,如果str1有确定的长度,后面就不会乱了,长度比ILOVEYOU长点也没关系 printf("str2 is %s\n",str2); //ILOVEYOU printf("str3 is %s\n",str3); //ILOVEYOU printf("str2[5] is %c\n",str2[5]); //ILOVEYOU while(*str3!='\0') { printf("%c",*str3); str3++; } printf("\nsizeof str0 is %d\n",sizeof(str0)); //20 printf("sizeof str1 is %d\n",sizeof(str1)); //9 printf("sizeof str2 is %d\n",sizeof(str2)); //9 printf("sizeof str3 is %d\n",sizeof(str3)); //4 printf("strlen of str2 is %d\n",strlen(str2)); //8 }
下面是几个基本函数操作,strcpy;strcat;strcmp,具体见下面的函数
#include <stdio.h> #include <strings.h> #include <malloc.h> int main(void) { char str3[20]="ILOVEYOU"; char *str4="ILOVEYOU"; int cmp1,cmp2;
//strcpy char *dst; dst=(char *)malloc(50); str4=str4+5; //指针偏移了 printf("str4 is %s\n",str4); //YOU strcpy(dst,str4); //把后面部分拷贝给dst printf("dst is %s\n",dst); //YOU
//strcat char *mes="hahaha"; strcat(dst,mes); //拼接 printf("dst is %s\n",dst); //YOUhahaha
//strcmp ,观察比较的两种方式 cmp1=strcmp(str3,str4); //-1 cmp2=strcmp(str3,"ILOVEYOU"); //0 printf("cmp1 is %d,cmp2 is %d\n",cmp1,cmp2); free(dst); }
在嵌入式中,字符串的操作也就差不多了。下面是一个具体的例子,来巩固一下。Change的作用是把文件名转换成大写,tell_type用来识别是不是wav文件。
观察change这个函数,加入char *str2="iii.jjj.wav",然后传入change函数,运行到*str2=*str2-32是会报错的,因为str2指向的是字符串常量,是不能被修改的。
而字符数组是可以修改的。然后既然是字符数组,为什么可以str++呢?前面第二点中,字符数组打印,不是不能str0/1/2++的吗?我的理解是,观察change函数的参数,当数组名传入的时候,可以被转换成了字符指针,相当于有一个字符指针,指向了这个字符数组。
#include <stdio.h> #include <strings.h> void change(char *str); int main(void) { char str2[]="iii.jjj.wav"; char str3[]="iii.jjj.wav.jpg"; change(str2); change(str3); tell_type(str2); tell_type(str3); } //如果是指针指向的数组,是不能被修改的。 //数组的才能被修改 void change(char *str) { while(*str!='\0') { if((*str>=97)&&(*str<=120)) *str=*str-32; //数组可以赋值,指针不行 str++; } } int tell_type(char *p) { int i=0; char *attr; while(i<100) { if(*p=='\0') //到末尾了 break; i++; p++; } if(i==100) return 1; i=0; while(i<5) { if(*p=='.') { p++; attr=p; break; } i++; p--; } if(i==5) return 2; if(strcmp(attr,"WAV")==0) { printf("%s is a WAV file\n",p); return 0; } else { printf("%s is not a wav file\n",p); return 4; } }
就像下面这个函数,定义了一个指针,指向这个字符数组。
void change(char *str); int main(void) { char str2[]="iii.JJJJ.wav"; char *s=str2; printf("%s\n",str2); while(*s!='\0') { if((*s>=97)&&(*s<=120)) *s=*s-32; //数组可以赋值,指针不行 s++; } printf("%s\n",str2); }