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