1、第8章 字符串,2,回顾,一维数组的定义、初始化 一维数组元素输入/输出 二维数组的定义、初始化 二维数组元素的输入/输出 必须用数组处理的一些问题,3,教学目标,理解字符串常量 理解字符数组和字符串的异同 使用字符串输入/输出函数 使用字符串处理函数 理解指针与字符串的关系 使用字符指针数组 使用字符串作为函数参数,4,字符串简介,char a=B; char b=r; char c=a; char d=k; char e=e; char f=r;,如何让程序存储我的姓名?,Braker,char name15=B,r,a,k,e,r;,用若干个字符,用字符数组,用字符串,5,字符串常量,字
2、符串常量是双引号括起的任意字符序列,“Hello World“ “WangPing“ “Please enter your full name:“ “Hello “UPC“,字符串常量中可以包含转义序列,字符串结束符,6,字符串与字符数组,在语言中没有专门的字符串变量,通常用一个字符数组来存放一个字符串 字符串 一串以0结尾的字符在C语言中被看作字符串 用双引号括起的一串字符是字符串常量,C语言自动为其添加0终结符 C语言并没有为字符串提供任何专门的表示法,完全使用字符数组和字符指针来处理 字符数组 每个元素都是字符类型的数组,如 char name20; 字符数组和字符串的区别是:字符串的末
3、尾有一个空字符0,没有结束符就不能按照字符串处理。,7,一维字符数组的初始化,字符串可按如下方式声明并初始化: 1.用字符型数据对数组进行初始化 char name15=W,a,n,g,L,i,0;2.用字符串常量直接对数组初始化 char name15 = “WangLi“; char password = “12345678“;,手工加入一个空字符,系统将自动加入一个空字符,省略数组大小,系统自动计算,大小为后面的字符总数加1,最后一个元素存入一个空字符。,8,一维字符数组的初始化,问题: char ch6=“123456“;char ch6=“1234567“;char ch6=“123
4、“; 输出数组元素的结果是什么?(看示例),9,字符串的输入输出,对于字符串(字符数组),在程序中既可以逐个引用字符串中的单个字符(数组元素) 也可以一次引用整个字符串(字符数组)(与数值型数组的区别),10,对字符数组逐个元素输入/输出,for (i=0; i10; i+) si=getchar(); ,char s10;,for (i=0; si!=0; i+) putchar(si); putchar(n);,11,字符串I/0函数,char name10;,scanf(“%s“, name);,printf(“%s“, name);,格式描述串中使用转换字符串“%s“,Wang Li,
5、Wang,12,字符串示例,#include int main(void) char s115;char s2=A,u,d,r,e,y,0;char s3=“Michael Holding“;int cnt=0;printf(“n 请向数组中输入一个姓名:“);scanf(“%s“,s1);printf(“n 显示字符串 n“);printf(“第一个字符串是:“);while(s1cnt!=0)printf(“%c“,s1cnt);cnt+;printf(“n 第二个字符串是:“);printf(“%s“,s2);printf(“n 第三个字符串是:“);printf(“%sn“,s3);r
6、eturn 0; ,13,字符串I/0函数,char name10; gets(name); puts(name);,Wang Li,Wang Li,从键盘上读入一个完整的行,存入字符数组name。并用空字符0取代行尾的换行符n。,把字符数组中的字符串输出到显示器。,14,字符串I/0函数,puts 函数完全可以由 printf 函数取代。 当需要按一定格式输出时,通常使用 printf 函数。,printf(“n 雇员姓名是: “); puts(name); printf(“n 雇员所属部门是: “); puts(dept);,printf(“n 雇员姓名是:%s“,name); print
7、f(“n 雇员所属部门是:%sn“,dept);,使用puts函数输出字符串,使用printf函数输出字符串,15,字符串示例,#include int main(void) char line30;int i,count = 0;printf(“n 请输入一行字符:n “);gets(line);i=0;while(linei !=0)if(linei =)count+;i+;printf(“n 其中的空格总数为 %d n “,count);return 0; ,C is a programming language,在循环执行时,扫描整个数组以统计出空格 的数量,直到遇到字符0。每次循环执
8、行时,都会更新计数器 i 和 count。,其中的空格总数为 4,16,字符串示例,#includeint main(void) char name30;char address30;puts(“请输入您的姓名:“);gets(name);fflush(stdin);puts(“请输入您的地址:“);gets(address);fflush(stdin);printf(“n您的姓名和地址是:n“);puts(name);puts(address);return 0; ,17,scanf和gets使用注意事项,scanf和gets都可以给字符数组赋值,scanf不能读入带空格的字符串,gets可
9、以。 但是scanf和gets两种用法都不安全,当用户输入的字符个数多于字符数组的维数时,数组将产生越界。 scanf被公认为最易遭到黑客攻击的函数之一 gets()也没有提供限制输入字符串长度的方法,容易引起缓冲区溢出,给黑客攻击以可乘之机 对输入字符串长度有限制的函数调用 fgets(buf, sizeof (buf), stdin);,18,一维字符数组举例,统计字符串中每个字符出现的次数。,基本思路:开一个“统计数组”记录每个字符出现的次数。 关键:每个字符与数组中进行计数的元素之间的对应关系。 方法:根据ASCII码的性质,将字符作为统计数组中元素的下标。,int count128;
10、,19,一维字符数组举例,#include int main ( ) int count128=0*128; /* 统计数组,初始化时全为 0 */char line200;int k=0;printf (“Enter String:“);gets (line);while (linek!=0) /* 对字符进行统计 */count linek+; /* 将字符作为下标*/for(k=0;k0)printf(“%c=%dt“,k,countk);return 0; ,20,一维字符数组举例,输入一行字符,将其中的每个字符从小到大排列后输出。,#include int main ( ) char
11、 string 100, t;int i, j, n;gets ( string );n = strlen ( string );for ( i=0; i stringj+1 ) t = stringj;stringj = stringj+1;stringj+1 = t;puts ( string );return 0; ,21,二维字符数组,二维字符数组的定义和初始化,可将二维数组当作一维数组使用,这个一维数组中的每个元素是个一维数组。,char a38=“str1“,“str2“,“string3“; char b 6=“s1“,“st2“,“str3“;,char a23 ,b35;,2
12、2,二维字符数组,二维字符数组的引用,for (i=0;i2;i+)printf(“%sn“,ai); /* 输出i行字符串 */ for (i=0;i2;i+)printf(“%cn“,aii); /* 输出i行i列字符 */ for (i=0;i2;i+)printf(“%sn“, /* 输出i行i+1列字符开始的字符串 */,char a23 ,b35;,23,二维字符数组举例,例:输入英文的星期几,确定对应的数字。可以查星期表,若发现与表中某项相同(英文的星期几), 则输出该字符串在表中的位置(序号);若查到表尾仍不相同, 则输出错误信息。可以建立如下星期表:,用二维字符数组存储星期表
13、,每行存一个字符串,24,二维字符数组举例,#include int main ( ) int i,k; char id10;char w_day 10=“Sunday“,“Monday“,“Tuesday“,“Wednesday“,“Thursday“,“Friday“, “Saturday“ ;printf(“Enter a string:“); scanf(“%s“,id);for (i=0; i7; i+) for(k=0;idk!=0;k+) if(w_dayik=idk)continue;elsebreak;if (idk =0) break; if (i7) printf (“%
14、s is %dn“, id, i);else printf (“Error !n“);return 0; ,25,字符串处理函数,与字符串有关的内置函数在头文件string.h中定义 要使用标准库字符串处理函数,程序前应该包含:#include ,string.h,strlen,strcpy,strcmp,strcat,26,字符串的长度,字符串的长度是字符串中位于结束标识0之前的所有字符的个数,#include int main() char str=“abcdefg“;int i, iLength=0;while( striLength !=0 )iLength+;printf(“Leng
15、th of string:n“);for( i=0; iiLength; i+ )printf(“%c“, stri );printf(“n is %dn“, iLength );return 0; ,while( str+iLength !=0 ) ;,length=7,27,求字符串长度函数,语法strlen(s); 描述 计算字符串s中字符的个数,并将字符的个数作为函数的返回值。在计算字符个数时不计表示字符串结束的空字符0。,strlen,#include #include int main(void) char arr = “Beijing“;int len1, len2;len1 =
16、 strlen(arr);len2 = strlen(“Shanghai“);printf(“n string = %s length = %d“, arr, len1);printf(“n string = %s length = %d n“,“Shanghai“,len2);return 0; ,string = Beijing length = 7string = Shanghai length = 8,28,字符串复制,将字符串 str1 拷贝到串 str2 中。根据字符串中 0 的位置,只对 0 前面的字符进行复制。,#include int main ( ) char str110
17、0, str2100;int i;printf (“Enter string 1:“);gets (str1); /* 输入字符串str1 */for (i=0;(str2i=str1i)!=0; i+) ;/* 复制*/ printf(“Output string 2:%sn“, str2);return 0; ,a,b,.,.,.,f,g,0,str1,str2,.,.,.,29,#include int main ( ) char str1100, str2100,str3100;int i;printf (“Enter string 1:“);gets (str1); for (i=0
18、;(str3i=str1i)!=0; i+) ;for (i=0;(str1i=str2i)!=0; i+) ;for (i=0;(str2i=str3i)!=0; i+) ; printf(“Output string 2:%sn“, str2);return 0;,30,#include #inlcude int main ( ) char str1100, str2100,str3100;int i;printf (“Enter string 1:“);gets (str1); strcpy(str3,str1);strcpy(str1,str2);strcpy(str2,str3);f
19、or (i=0;(str2i=str3i)!=0; i+) ; printf(“Output string 2:%sn“, str2);return 0;,31,字符串复制函数,语法strcpy(dest,src) 描述 其中,dest是目标字符串,src是源字符串。相当于把字符数组src中的字符串拷贝到字符数组dest中。结束标志0也一同拷贝。src可以是一个字符串常量。字符数组dest应足够大,以保证字符串复制不越界。,strcpy,#include #include int main(void) char source = “We change lives“;char target20;
20、strcpy(target,source);printf(“n 源字符串 = %s“, source);printf (“n 目标字符串 = %sn“, target);return 0; ,源字符串 = We change lives目标字符串 = We change lives,字符串不能直接整体复制, 必须借助strcpy!,32,字符串比较函数,语法strcmp(str1, str2) 描述 按照ASCII码顺序比较字符串str1和str2的大小,比较的结果由函数返回。在两个字符串str1和str2相同时返回0;字符串str1大于字符串str2时返回一个正值,否则就返回负值。,strc
21、mp,#include #include int main(void) char username15,pwd15;printf(“n 请输入用户名: “ );gets(username);printf(“n 请输入密码: “);gets(pwd);if(strcmp(username,“John“)=0) ,请输入用户名: john请输入密码: 123456用户名和/或密码无效,请输入用户名:John请输入密码: 123456您已成功登录,字符串不能用关系运算符比较大小, 必须借助strcmp!,“abc“ 与 “abc“ , 相等 “abcd“ 与 “abck“, “abcd“ 小 “ab
22、c“ 与 “ab“, “abc“ 大,33,字符串函数使用示例,从键盘任意输入5个学生的姓名,编程找出并输出按字典顺序排在最前面的学生姓名 等价于求最小字符串,34,字符串函数使用示例,#include #include #define ARRA_SIZE 80 int main() int n, num;char strARRA_SIZE, minARRA_SIZE;printf(“Please enter five names:n“);gets(str); strcpy(min, str); for (n=1; n5; n+)gets(str); if (strcmp(str, min)
23、0) strcpy(min, str); printf(“The min is %s:“,min);return 0; ,35,字符串连接,将串str2连接到串str1之后。根据字符串中 0 的位置进行字符串连接。关键:要用str2的第1个字符覆盖str1的串结束标记0。,算法: 1、查找str1的串结束标记0 2、从str1的0开始,将str2复制到str1后面。,a,b,c,d,e,f,g,0,str2,str1,.,.,.,36,字符串连接,#include int main( ) char str1100,str2100;int i, j;printf (“Enter string 1
24、:“);gets (str1);printf (“Enter string 2:“);gets (str2);for ( i=0; str1i!=0; i+ ) ; /* 确定0位置 */for ( j=0; (str1i=str2j) != 0; i+, j+ ) ;printf(“Output string 1:%sn“, str1);return 0; ,37,字符串连接函数,语法strcat(dest, src) 描述 把字符串 src中的字符串连接到字符串 dest中字符串的后面。本函数返回值是字符数组dest的首地址。连接后字符串的总长度将是字符串 src 的长度加上字符串 des
25、t的长度。目标字符串dest的大小应足够存储最终的字符串。,strcat,#include #include int main(void) char source_string = “UPC“;char target_string30 = “Hello “;strcat(target_string,source_string);printf(“n 源字符串 = %s“, source_string);printf(“n 目标字符串 = %sn“, target_string);return 0; ,源字符串 = UPC目标字符串 = Hello UPC,38,字符串大写转小写函数,#inclu
26、de #includeint main(void) char str150;printf(“n 请输入一个大写格式的字符串:n“);gets(str1);printf(“n“);printf(“ 原始字符串为:%sn“,str1);/用strlwr()将字符串转换为小写格式printf(“ 转换后的字符串为:%sn“,strlwr(str1);return 0; ,39,字符串反向,在字符串中将首尾字符进行对调,int main ( ) char str100, c; int i, j;printf (“Enter string:“); gets (str);for ( i=0; stri!=
27、0; i+ ) ; i-; for ( j=0; ji; i-, j+ )c=stri; stri=strj; strj=c;printf(“Output string:%sn“, str);return 0; ,a,k,j,b,c,i,j=0,1,2,3,i=10,9,8,7,/* 确定0的位置 */,/* i 指向0之前的最后一个字符 */,/* 向中间逐步交换 i 和 j 指向的字符 */,算法:当 j i时,逐步交换 i 和 j 指向的字符,40,字符串处理函数,#include #includeint main(void) char msg=“Fly like a BUTTERFLY
28、 and String like a BEE“;printf(“n 原始字符串为:%sn“,msg);/用strrev()将字符串进行左右反转printf(“n 左右反转后的字符串为:%sn“,strrev(msg);return 0; ,41,总结,字符串与字符数组的区别是字符串的末尾有一个空字符0以标识字符串结束 用scanf()语句读入字符串时不允许输入中存在空格 gets() 和 puts() 函数分别用于字符串的输入和输出 在 string.h 中定义了很多字符串处理函数函数,比较常用的有:strcpy()、strcat()、strcmp() 和 strlen() 假如程序里需要一组字符串,一种常用的做法就是用一个字符指针数组表示它们 字符串可以作为参数,函数传递机制同数组作为参数,为引用方式,42,Thank you,Question?,