第7章字符串及其应用_第1页
第7章字符串及其应用_第2页
第7章字符串及其应用_第3页
第7章字符串及其应用_第4页
第7章字符串及其应用_第5页
已阅读5页,还剩79页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

C语言的字符串表示方法字符串的常用处理方法及标准库函数

第7章字符串及其应用在C中,字符串的表示和处理是通过字符数组来实现的,和其它类型的数组一样,只需要知道其起始位置,而起始位置可以用数组名或者指针来表示。

主要有两种方式来表示字符串,这两种方式是:使用指向字符类型变量的指针

通过定义字符类型指针变量,并将字符串或字符串常量的首地址赋给该指针,此后可以用该指向字符串的指针变量来表示其所指向的字符串数据,例如

char*sPtr;*sPtr=”ThisisCString.”;

使用字符数组

首先定义字符类型的数组,然后将字符串数据的每一个字符依次存放到指定的字符数组中,此后的程序代码中可以使用该字符数组的名字表示其所存放的字符串数据。例如语句

charstr[7]=”abcd”

7.1C语言的字符串表示方法两种字符串数据表示方式的根本区别

(1)定义一个字符类型指针变量表示字符串

例如语句char*sPtr=”abcd”;

系统处理的方法是首先在系统的内存储器中分配一段连续的存储区域并存放指定的字符串常量,然后将该存储区域的起始地址(字符串常量的首地址)赋值给字符类型指针变量sPtr,字符指针变量与其所指向的字符串常量之间的关系如图7.1a所示。由于sPtr是指针变量,可以根据需要指向任意合法的字符数据对象,所以在此后的程序代码中任何修改其指向的操作都是合法的,例如使用语句sPtr=”1234”使得指针变量sPtr改变指向从表示字符串数据”abcd”转变成为表示字符串数据”1234”,sPtr与其所指向的字符串常量之间的关系如图7.1b所示。

7.1.1字符串表示方法

abcd\0sPtra)指针变量指向字符串常量abcd\0abcd\0sPtrb)指针变量改变原指向指向另一字符串1234\0图7.1指针变量与字符串数据对象的关系示意图7.1.1字符串表示方法

(2)定义字符类型数组表示字符串

例如语句charstr[7]=”abcd”;,其本质意义是首先为字符数组str按指定长度在系统的内存储器中分配连续的存储区域,字符数组的名字str表示这段连续存储区域的起始地址,然后将该存储区域的内容初始化为字符串数据”abcd”,字符数组str与其初始值之间的关系如图7.2所示。abcd\0\0

\0str图7.2数组名与其初始化值之间的对应关系7.1.1字符串表示方法

程序代码中任何试图修改数组名str值的操作或者试图为数组整体赋值的操作都是错误的,请比较下面的两段代码:

/*正确的程序代码段*/char*sPtr=”abcd”;…

sPtr=”1234”; /*改变指针变量sPtr的指向*//*错误的程序代码段*/charstr[7]=”abcd”;…

str=”1234”;//错误赋值操作,试图将数组作为整体操作7.1.1字符串表示方法字符数组初始化的两种主要方法

(1)使用单个字符常量初始化字符数组用单个字符初始化时,将常量表中的字符依次赋值给对应的字符数组元素。在初始化时应注意以下几点:常量表中的单个字符使用单引号,最后一个字符应该是字符串结尾符号'\0'字符;部分初始化时未赋值部分仍然是'\0'字符;如果常量表中提供了所有的字符(包含'\0'),可以省略数组的长度;下面是几个单个字符常量初始化字符数组的示例:

chars1[9]={'N','e','w','','Y','e','a','r','\0'};chars2[9]={'H','e','a','d','\0'};chars3[]={'N','e','w','','Y','e','a','r','\0'};

chars4[]={‘N’,‘e’,‘w’,‘\0','Y','e','a','r','\0'};7.1.1字符串表示方法当遇到\0时就表示字符串结束,S4的有效字符串是New,3个。其字符串的长度为3+1。

(2)使用字符串常量初始化字符数组 使用字符串常量对字符数组进行初始化时,系统会自动在末尾加上字符串结尾符号'\0',但定义的字符数组必须提供足够的长度。在初始化时应该注意以下几点:字符串常量只需要提供有效字符数据;字符串常量不足以填满整个字符数组空间时仍然使用'\0'字符填充;字符串常量数据可以使用花括号括住,也可以不使用花括号;如果没有指定字符数组的长度,系统自动指定为字符串常量中有效字符的个数+1;下面是几个字符串常量初始化字符数组的示例:chars1[80]={"NewYear"};chars2[80]=“NewYear”;//可以省略花括号{}chars3[]="NewYear";//此时字符数组的长度为97.1.1字符串表示方法字符串数据的输入

C中通过函数scanf()和gets()来实现/*使用格式控制项%逐个输入*/charstr[10];intj;for(j=0;j<9;j++)

scanf(“%c”,&str[j]);str[j]=’\0’;/*为了保证字符串数据的完整性,自行处理字符串结尾符号*//*使用格式控制项%s全部输入*/charstr[10];scanf(“%s”,str);/*字符串数据作为整体处理,系统会自动处理结尾符号*/

在使用标准库函数gets时,将字符串数据作为一个整体来看待如下所示:/*使用标准库函数gets*/charstr[10];gets(str);/*字符串数据作为整体处理,系统会自动处理结尾符号*/7.1.2字符串的输入输出getchar()-输入一个字符,不能输入字符串使用格式控制项%s全部输入或者输出字符串的注意事项正确的输入输出:charstr[10]scanf((“%s”,str);/*从键盘输入字符串并存于字符数组str中*/printf(“%s”,str);/*输出字符数组str*/printf(“%s”,&str[2]);/*输出字符数组str中从第3个字符开始的字符串*/错误的输入输出:charstr[10]scanf(“%s”,str[2]);/*str[2]是字符数组类型,和%s不匹配*/scanf(“%s”,&str);/*str是字符数组名代表了数组的首地址,不应该在数组名前加取地址运算符*/print(“%s”,str[5]);/*函数中的输出项应该为字符串名,而不应该是字符数组元素名。*/

7.1.2字符串的输入输出scanf函数gets函数在使用时的两个不同之处

(1)一次函数调用可以输入的字符串数据个数不同

scanf(“%s%s”,str1,str2);/*一次调用可以输入多个用空格分隔的字符串*/gets(str1);/*一次调用只能够输入一个字符串*/例如:输入howdoyoudocharstr1[5],str2[5],str3[5],str4[5];scanf(“%s%s%s%s”,str1,str2,str3,str4);其存储形式为:str1str2str3str4

7.1.2字符串的输入输出how\0do\0you\0do\0scanf函数gets函数在使用时的两个不同之处

(1)一次函数调用可以输入的字符串数据个数不同

scanf(“%s%s”,str1,str2);/*一次调用可以输入多个用空格分隔的字符串*/gets(str1);/*一次调用只能够输入一个字符串*/

(2)空格字符的处理不同使用标准库函数scanf时,由于空格字符作为两个字符串数据的分隔符出现,所以在输入的字符串数据中不能含有空格字符;而使用标准库函数gets时,输入的字符串数据中可以含有空格字符。

gets(str);/*从键盘上输入howdoyoudo保留在str中,后续可以使用配对的put(str)输出*/7.1.2字符串的输入输出2)字符串数据的输出/*调用标准库函数printf使用格式控制项%c*/intj=0;…while(str[j]!=’\0’)/*用处理数组的概念处理字符串*/printf(“%c”,str[j++]);…/*调用标准库函数printf使用格式控制项%s*/…printf(“%s”,str); /*将字符串数据作为整体看待*//*使用标准库函数puts*/…puts(str); /*将字符串数据作为整体看待*/7.1.2字符串的输入输出printf函数和puts函数在使用时的两个不同之处

(1)一次调用能够输出的字符串个数不同

printf(“%s\n%s”,str1,str2);/*一次调用输出两个以上的字符串数据*/puts(str1)/*一次调用只能输出一个字符串数据*/

(2)输出数据换行处理方式不同 使用标准库函数puts输出字符串数据时,输出完成后会自动进行换行;而使用标准库函数printf时,一个字符串数据输出完成后不会自动换行,若需实现换行功能,需要在格式控制字符串中的适当位置插入换行字符’\n’。

例7-1

字符串数据的输入输出示例。

7.1.2字符串的输入输出/*Name:ex07-01.cpp*/#include<stdio.h>#defineN100voidmain(){ chars1[N],s2[N],s3[N],s4[N];

inti;

printf("单个字符输入方式1:\n");

for(i=0;i<N;i++) /*用字符方式输入字符串*/ { scanf("%c",&s1[i]); if(s1[i]=='\n') break; } s1[i-1]=‘\0’;/*最后一个字符即s1[99]是结束符号,有效字符到s1[98]就结束*/

printf("单个字符输入方式2:\n");

for(i=0;i<N;i++) /*用字符方式输入字符串*/ if((s2[i]=getchar())=='\n') break;

s2[i-1]='\0';/*最后一个字符即s2[99]是结束符号,有效字符到s2[98]就结束*/

printf("字符串整体输入方式1:\n"); gets(s3); /*字符串作为整体输入,系统会自动添加结尾符号*/

printf("字符串整体输入方式2:\n"); scanf("%s",s4);/*字符串作为整体输入,系统会自动添加结尾符号*/

printf("\n");

for(i=0;s4[i]!='\0';i++) /*用单个字符处理形式输出字符串*/ putchar(s4[i]);

printf(“\n”); /*对上面的输出处理完成后换行*/ printf("%s%s\n",s3,s2); /*输出两个字符串,自行处理换行*/ puts(s1); /*输出一个字符串,系统自动换行*/}例7-2

将字符串中小写字母转变成大写字母。/*Name:ex07-02.cpp*/#include<stdio.h>voidmain(){ charstring[100],*p;

printf("Pleaseinputastring:");

gets(string);

p=string; while(*p!='\0') { if(*p>='a'&&*p<='z') *p-=32; p++;/*移动指针变量对字符串中的字符依次进行处理*/ }

printf("Thenewstringis:");

puts(string);}7.1.2字符串的输入输出指针指向字符串的首地址,相当于赋初值C语言的字符串表示方法字符串的常用处理方法及标准库函数第7章字符串及其应用字符串中有效字符的统计字符串的复制字符串的连接字符串中字符的查找字符串中字符的插入和删除字符串的比较和子串的查找字符串中子串的插入和删除字符串与二维字符数组7.2字符串的常用处理方法及标准库函数字符串中有效字符的统计

所谓测试字符串的长度就是统计字符串中包含的有效字符个数。统计字符串中有效字符个数的基本思想非常简单,只需要从字符串数据的的第一个字符位置开始,依次向后判断该位置的字符是否系统规定的字符串数据结尾字符(’\0’),当不是字符串数据结尾字符时则予以统计,直到遇到系统规定的字符串数据结尾符号为止。

例7-3

字符串长度测试函数的原型为:

int

strlength(chars[]);

编制该函数并用相应主函数进行测试。7.2.1字符串中有效字符的统计/*Name:ex07-03.cpp*/#include<stdio.h>voidmain(){int

strlength(chars[]); charstr[100];

printf("Inputthestring:");

gets(str);

printf("Thelengthofstringis%d\n",strlength(str));}int

strlength(chars[]){ inti;

for(i=0;s[i]!='\0';i++) ; returni;}7.2.1字符串中有效字符的统计循环变量i是字符个数,也就是字符串的有效字符个数即长度int

strlength(char*s){inti=0;while(*s)

i++,s++;returni

在C标准库中提供了测试字符串长度的标准库函数strlen,函数的原型为:

size_t

strlen(constchar*string);

函数原型中的size_t是系统定义好的用于统计存储单元个数和重复次数的数据类型,实质上就是整型数据类型。函数的功能是:返回(获取)由string表示的字符串数据中的有效字符个数,统计在遇到字符串数据中的第一个系统字符串结尾字符’\0’时结束。

const含义:表示指针指向的是常量,不允许对内容string进行修改。

7.2.1字符串中有效字符的统计/*Name:ex07-03-1.cpp*/#include<stdio.h>#include<string.h>

/*字符串标准函数库*/voidmain(){charstring[100];

intl;

printf(“请输入字符串\n");

gets(string);

l=strlen(string);

printf("字符串长度=%d\n",l);}size_t

strlen(constchar*string);

/*字符串长度原型的声明*/例7-4

颠倒字符串函数的原型为:

voidreverse(chars[]);

请编制该函数并用相应主函数测试。例如,输入abcd,输出时显示dcba。

例7-5

一个从左读或从右读都是相同的单词称为回文,例如level是回文。编程序实现功能:判断输入一个字符串是否回文。

7.2.1字符串中有效字符的统计/*Name:ex07-04.cpp*/#include<stdio.h>#include<string.h>voidmain(){ voidreverse(char

*s);/*函数的声明*/ chars[100];

printf("Inputthestring:");

gets(s);

reverse(s);

puts(s);}voidreverse(char

*s){ inti=0,j=strlen(s)-1,t;/*有效字符下标从0开始,到strlen(s)-1结束*/

for(;i<j;i++,j--) { t=s[i];

s[i]=s[j];

s[j]=t; }}第1个字符和最后1个字符交换/*Name:ex07-05-1.cpp*/#include<stdio.h>#include<string.h>voidmain(){ charword[80];

int

i,j,flag=1; puts("请输入一个单词:");

gets(word); j=strlen(word)-1;//获取字符串的长度

for(i=0;i<j;i++,j--) {if(word[i]!=word[j]) flag=0; break; }

if(flag)

printf("单词'%s'是回文!\n",word); else

printf("单词'%s'不是回文!\n",word);}/*Name:ex07-05.cpp*/#include<stdio.h>#include<string.h>voidmain(){ charword[80],*head,*end;

int

len,flag=1; puts("请输入一个单词:");

gets(word);

len=strlen(word);//获取字符串的长度

head=word; //初始时,head指针指向字符串的首字符

end=head+len-1; //初始时,end指针指向字符串的最后一个有效字符

while(*head=='')//移动头指针跳过字符串的前导空格

head++;

while(*end=='')//移动尾指针跳过字符串的后续空格

end--;

for(;head<end;head++,end--) { if(*head!=*end) //遇到对应位置字符不同则停止比较

{ flag=0; break; } }

if(flag)/*flag=1时*/

printf("单词'%s'是回文!\n",word); else

printf("单词'%s'不是回文!\n",word);}字符串中有效字符的统计字符串的复制字符串的连接字符串中字符的查找字符串中字符的插入和删除字符串的比较和子串的查找字符串中子串的插入和删除字符串与二维字符数组7.2字符串的常用处理方法及标准库函数字符串的复制

字符串复制(拷贝)就是复制已经存在字符串的所有字符到指定目标位置,其基本思想是:从源字符串数据的第一个字符开始依次取出源字符串中的每一个字符,只要该字符不是系统规定的字符串结尾符号就将其赋值到指定的目标位置,直到源字符串中的所有有效字符取完为止。

例7-6

函数的原型为:voidstrcopy(chars[],chart[]);,其功能是将t所表示的字符串复制到s中去,请编制该函数并用相应主函数测试。

7.2.2字符串的复制/*Name:ex07-06.cpp*/#include<stdio.h>voidmain(){ voidstrcopy(char

s[],chart[]); chars1[80],s2[80];

printf("Inputthestringstr1:"); gets(s1); strcopy(s2,s1); puts(s2);}voidstrcopy(char

s[],chart[]){ inti;

for(i=0;t[i]!='\0';i++)

s[i]=t[i];

s[i]='\0';}依次取出字符串t的字符赋给s的当前位置。然后双双移动到下一个字符继续…直到遇到结束符号为止。

标准函数库中提供了相应的字符串拷贝函数,函数的原型为:

char*strcpy(char*strDestination,constchar*strSource);

函数的功能是:将由strSource表示的源字符串拷贝到由strDestination指定的目标地址中,然后返回strDestination;strDestination所代表目标字符串的字节长度必须满足strSource所代表字符串的长度要求。

例7-7

使用C标准库函数strcpy实现字符串的拷贝。7.2.2字符串的复制7.2.2字符串的复制/*Name:ex07-07.cpp*/#include<stdio.h>#include<string.h>/*包含字符处理所有函数的头函数*/voidmain(){ chars1[80],s2[80];

printf("Inputthestringstr1:"); gets(s1); strcpy(s2,s1); puts(s2);}字符串的复制应注意的事项

在实际的程序设计中,有可能存在着将源字符串从某一位置开始的字符拷贝到目标字符串的要求,对于这种要求可以通过调用函数时使用合适的实际参数予以满足,注意到下面三个重要事实:字符串的复制字符串处理函数中使用的字符数组样式形式参数本质上是一个指针量(地址量),对应的实际参数只需要地址量即可。在第4章中讨论过数组作参数的部分共享问题,可以将实参字符串的部分提供给形参数组共享。C语言中的字符串在存储时系统会为其添加字符串结尾符号,程序中处理字符串时只需要指出开始位置即可。7.2.2字符串的复制

例7-8

编程序实现将源字符串从指定位置开始拷贝到目标字符串的功能。/*Name:ex07-08.cpp*/#include<stdio.h>#include<string.h>voidmain(){ chars1[80],s2[80];

intpos;

printf("Inputthestrings1:"); gets(s1);

printf("Inputthepos:");

scanf("%d",&pos);

strcpy(s2,&s1[pos]);//也可以用strcpy(s2,s1+pos);语句

puts(s2);}

例7-9

编程序实现将字符串的某部分删除的功能,删除的起点和长度从键盘输入。如果字符串中从起点开始剩余的字符数据不能满足长度要求则删去从起点开始的所有字符。7.2.2字符串的复制

例7-9

编程序实现将字符串的某部分删除的功能,删除的起点和长度从键盘输入。如果字符串中从起点开始剩余的字符数据不能满足长度要求则删去从起点开始的所有字符。#include<stdio.h>#include<string.h>voidmain(){ chars[100];int

start,len,length;

printf("请输入被处理的字符串:");

gets(s);

printf("请输入删除的起始点位置:");

scanf("%d",&start); //从键盘上获取删除的起点位置

printf("请输入欲删除的字符个数:");

scanf("%d",&length);//从键盘上获取欲删去的字符个数

len=strlen(&s[start]);//获取自删除起始点开始至串尾的字符个数

if(len<length)

strcpy(s+start,s+strlen(s));//剩余部分不能满足删除要求时

else

strcpy(s+start,s+start+length);//剩余部分能够满足删除要求时

puts(s);}字符串中有效字符的统计字符串的复制字符串的连接字符串中字符的查找字符串中字符的插入和删除字符串的比较和子串的查找字符串中子串的插入和删除字符串与二维字符数组7.2字符串的常用处理方法及标准库函数字符串的连接

所谓字符串的连接本质上也是字符串拷贝,与字符串复制不同的是需要将指定的源字符串数据中的每一个字符依次拷贝到指定的目标字符串最后一个有效字符的后面而不是目标串中的第一个位置。实现字符串连接的基本思想是:首先找到目标字符串的结尾处,然后从源字符串的第一个字符开始依次取出每一个有效字符并依次赋值到指定目标位置,直到源字符串中的字符处理完成为止。

例7-10

函数原型为:voidstrjoin(char

s[],chart[]);,其功能是将t所表示的字符串连接到s所表示的字符串末尾,请编制该函数并用相应主函数测试。7.2.3字符串的连接/*Name:e0x7-10.cpp*/#include<stdio.h>voidmain(){ voidstrjoin(chars[],chart[]); chars1[80],s2[80];

printf("Inputs1&s2:\n"); gets(s1);gets(s2); strjoin(s1,s2); puts(s1);}voidstrjoin(char

s[],chart[]){ int

i,j=0;

for(i=0;s[i]!='\0';i++); //寻找前串的末尾

for(j=0;t[j]!='\0';j++,i++)//实现字符串连接

s[i]=t[j];

s[i]='\0';}

在标准函数库中提供了相应的字符串连接函数,函数的原型为:

char*strcat(char*strDestination,constchar*strSource);

函数的功能是:将由strSource

表示的源字符串拷贝到由strDestination表示的目标字符串的末尾(即连接到strDestination所表示的字符串后),然后返回strDestination;strDestination所代表目标字符串的字节长度必须满足两个字符串连接后的长度要求。

7.2.3字符串的连接/*Name:ex07-11.cpp*/#include<stdio.h>#include<string.h>voidmain(){ chars1[80],s2[80];

printf("Inputs1&s2:\n"); gets(s1); gets(s2);

strcat(s1,s2); puts(s1);}7.2.3字符串的连接Inputs1&s2:ABCDE12345ABCDE12345

例7-11

使用C标准库函数strcat实现字符串的连接。

#include<stdio.h>#include<string.h>voidmain(){ chars1[80],s2[80];

intpos;

printf("Inputs1ands2:\n"); gets(s1); gets(s2);

printf("Inputthepos:");

scanf("%d",&pos); strcat(s1,&s2[pos]); puts(s1);}7.2.3字符串的连接Inputs1ands2:ABCDEFG12345Inputthepos:3//这里的3是指s2[3]元素,不是12345字符的3ABCDEFG45例7-12

编程序实现将源字符串从指定位置开始连接到目标字符串的功能。字符串中有效字符的统计字符串的复制字符串的连接字符串中字符的查找字符串中字符的插入和删除字符串的比较和子串的查找字符串中子串的插入和删除字符串与二维字符数组7.2字符串的常用处理方法及标准库函数字符串中字符的查找

所谓字符串中字符的查找就是按照指定的方向寻找指定字符第一次在字符串中出现的位置。在字符串中查找指定的字符从查找方向上可以分为正向查找(从串首部至串尾)和反向查找(从串尾部至串首),从获取被查找字符位置信息上可以分为返回下标序号方式和返回字符存放地址方式。7.2.4字符串中字符的查找字符串中正向查找指定字符

在字符串中正向查找指定字符第一次出现位置的基本思想是:从被操作字符串的第一个字符开始循环依次取出被操作字符串当前位置的字符与指定的字符相比较,若比较相符合则返回该字符的位置;否则进行下一轮比较直到被处理的字符串中所有字符取完为止。

例7-13

编制函数实现功能:在字符串中正向查找指定的字符,若被查找字符存在则返回字符在字符串中的下标序号;若指定的字符在被查找的字符串中不存在,则返回-1;并用相应主函数进行测试。

C语言的查找字符的标准库函数为:

char*strchr(constchar*string,intc)功能:查找字符c在字符串string中首次出现的位置,NULL结束符也包含在查找中.返回一个指针,指向字符c在字符串string中首次出现的位置,如果没有找到,则返回NULL.7.2.4字符串中字符的查找/*Name:ex07-13.cpp*/#include<stdio.h>voidmain(){ int

search_chr(chars[],charc); chars1[80],ch;intpos;

printf("Inputthestring:"); gets(s1); printf("Inputthecharacter:");

ch=getchar(); pos=search_chr(s1,ch);

if(pos!=-1)/*注意pos的初始位置是0*/

printf("Thepositioniss1[%d].\n",pos); else

printf("'%c'isnotin'%s'.\n",ch,s1);}int

search_chr(char

s[],charc){ inti;

for(i=0;s[i]!='\0';i++)

if(s[i]==c) returni; return-1;}/*Name:ex07-15.cpp*/#include<stdio.h>#include<string.h>voidmain(){ chars1[80],s2[80],s3[80]="",*pos; int

i,j;

printf("输入字符串s1:"); gets(s1);

printf("输入字符串s2:"); gets(s2);

for(i=0,j=0;s1[i]!='\0';i++) { pos=strchr(s2,s1[i]);

if(pos!=NULL&&strchr(s3,s1[i])==NULL) { s3[j++]=s1[i]; s3[j]='\0';} } s3[j]='\0'; if(strlen(s3)!=0) { printf("两个串中共有的字符串构成的字符串是:"); puts(s3); } else

printf("两个字符串s1和s2没有共同的字符存在!\n");}}字符串中反向查找指定字符

在字符串中反向查找指定字符第一次出现位置的基本思想是:从被操作字符串的最后一个字符开始循环依次取出被操作字符串当前位置的字符与指定的字符相比较,若比较相符合则返回该字符的位置;否则进行下一轮比较直到被处理的字符串中所有字符取完为止。

例7-16

编制函数实现功能:在字符串中反向查找指定的字符,若被查找字符存在则返回字符在字符串中的下标序号;若指定的字符在被查找的字符串中不存在,则返回-1;并用相应主函数进行测试。7.2.4字符串中字符的查找int

Rsearch_chr(char

s[],charc){ inti;

for(i=strlen(s)-1;i>=0;i--)

if(s[i]==c) returni; return-1;}

上面程序的函数Rsearch_chr实现方法与例7.13程序类似,惟一不同的地方是此时取出字符串中字符时是从字符串中的最后一个字符开始,字符串中最后一个字符的下标序号是:strlen(s)-1(字符串的长度减1)。7.2.4字符串中字符的查找字符串中有效字符的统计字符串的复制字符串的连接字符串中字符的查找字符串中字符的插入和删除字符串的比较和子串的查找字符串中子串的插入和删除字符串与二维字符数组7.2字符串的常用处理方法及标准库函数1)在字符串指定位置插入字符

在字符串指定位置插入一个字符的基本思想是:首先在字符串中查找指定的位置,然后将字符串中从指定位置以后的所有字符由后向前依次向后移动一个字符位置以腾出所需要的字符插入空间;最后将指定的插入字符拷贝到该指定位置即可。字符的插入包括前插(插入的字符在指定位置原字符之前)和后插(插入的字符在指定位置原字符之后)两种方式,这两种方式的基本思想完全一致,不同之处在于字符串部分字符后移时是否包括指定位置的原字符。

例7-17

编制函数实现功能:在字符串的指定字符之前插入另外一个指定字符,若在字符串中找不到插入位置,则将被插入字符添加到字符串末尾,并用相应主函数进行测试。7.2.5字符串中字符的插入和删除/*Name:ex07-17.cpp*/#include<stdio.h>#include<string.h>voidmain(){ voidinsertchr(chars[],charpos,charc);chars1[80],pos,ch;

printf("请输入被处理的字符串:");gets(s1);

printf("请输入被查找的字符:");pos=getchar(); getchar();

printf("请输入被插入的字符:");ch=getchar(); puts(s1);insertchr(s1,pos,ch);puts(s1);}voidinsertchr(char

s[],char

pos,charc){ intlast=strlen(s); char*p; p=strchr(s,pos);//使用标准库函数strchr在串s中寻找字符pos

if(p!=NULL)//如果找到插入点

{for(;&s[last]>=p;last--)//所有字符由后向前依次向后移动一个字符位置

s[last+1]=s[last]; *p=c; } else { s[last+1]=s[last];//实际是后退末尾的结束符\0

s[last]=c; }}2)在字符串中删除指定的字符

在字符串中删除指定字符操作的基本思想是:首先在字符串中查找指定字符的位置,若找到则将字符串中自该位置以后所有字符依次向前移动一个字符位置即可。

例7-18

函数原型为:voiddeletechr(chars[],charc);,其功能是在字符串中删除指定字符,若指定字符不存在则显示相应提示信息。请编制该函数并用相应主函数进行测试。7.2.5字符串中字符的插入和删除/*Name:ex07-18.cpp*/#include<stdio.h>#include<string.h>voidmain(){ voiddeletechr(chars[],charc);/*声明*/ chars1[80],ch;

printf("请输入被处理的字符串:"); gets(s1);

printf("请输入要删除的字符:");

ch=getchar(); puts(s1);

deletechr(s1,ch);/*调用删除函数*/ puts(s1);}voiddeletechr(char

s[],charc)/*定义*/{ char*p;

p=strchr(s,c); //找到被删除字符的位置

if(p!=NULL) strcpy(p,p+1);//字符串(p+1为起始地址)//拷贝到删除点覆盖被删字符

else

printf("'%c'不在'%s'中.\n",c,s);}从字符串的任一位置开始处理字符串。在串中删去某个字符可以通过将被删除字符后所形成的字符串拷贝到字符位置的方法实现。voiddeletechr(char

s[],charc)/*定义*/{ int

search_chr(char

s[],charc);/*声明字符查找函数*/

intpos; pos=search_chr(s,c); //在串s中查找字符c

if(pos!=-1)

for(;s[pos]!='\0';pos++)//删除点后的所有字符依次向前移动一个字符位置

s[pos]=s[pos+1]; else

printf("'%c'不在'%s'中.\n",c,s);}int

search_chr(char

s[],charc){ inti;

for(i=0;s[i]!='\0';i++)

if(s[i]==c) returni; return-1;}字符串中有效字符的统计字符串的复制字符串的连接字符串中字符的查找字符串中字符的插入和删除字符串的比较和子串的查找字符串中子串的插入和删除字符串与二维字符数组7.2字符串的常用处理方法及标准库函数1)字符串的比较

比较两个字符串的基本思想是:从参与比较操作的两个字符串的第一个字符开始依次比较相同位置的两个对应字符,在下列两种情况之下结束比较过程:两个字符串中对应位置字符的ASCII码不相同;遇到两字符串中任何一个字符串的串结尾字符’\0’;

比较结束时,用该时刻两个字符串中对应位置字符的ASCII码差值来确定两个字符串之间的关系。设参加比较操作的两个字符串分别用s1和s2表示(其中s1表示前串,s2表示后串),则字符串比较结果的判断规则为:7.2.6字符串的比较和字串的查找

例7-19

函数的原型为:int

strcompare(chars[],chart[]);,其功能是比较两个字符串s和t的关系,比较规则如上所示,请编制函数strcompare并用相应主函数进行测试。

7.2.6字符串的比较和字串的查找/*Name:ex07-19.cpp*/#include<stdio.h>voidmain(){ int

strcompare(chars[],chart[]); chars1[80],s2[80];

intresult;

printf("输入比较的前串s1:"); gets(s1);

printf("输入比较的后串s2:"); gets(s2); result=strcompare(s1,s2);

if(result>0) printf("s1>s2(前串大于后串)\n"); elseif(result<0) printf("s1<s2(前串小于后串)\n"); else printf("s1=s2(前串等于后串)\n");}int

strcompare(chars[],chart[]){ inti;

for(i=0;s[i]==t[i];i++)

if(s[i]=='\0') return0; returns[i]-t[i];}比较函数strcompare中,循环执行的条件是s[i]==t[i],即当遇到两个ASCII码值不相同的字符时循环结束,返回该位置两个字符ASCII码值之差(s[i]-t[i]);当循环条件成立时则判断是否两个字符串同时结束,若是同时结束则返回数值0表示两个字符串相同;当对应位置的两个字符既相同且又不是结尾符号时,则取出下一对字符进行比较。

在标准函数库中提供了相应的字符串比较函数,函数的原型为:

int

strcmp(constchar*string1,constchar*string2);

函数的功能是:比较两个字符串string1和string2的关系,返回值确定规则为:如果string1大于string2,则返回值大于0;如果string1等于string2,返回值等于0;如果string1小于string2,返回值小于0。

特别需要提醒读者注意的是,由于字符串本质上是字符数组,不能直接作为整体进行操作,所以不能用类似if(s1>s2)的方式直接对字符串s1和s2进行比较,而应该使用串比较函数。

例7-20

使用标准库函数比较两个字符串。

7.2.6字符串的比较和字串的查找/*Name:ex07-20.cpp*/#include<stdio.h>#include<string.h>voidmain(){ chars1[80],s2[80];

intresult;

printf("输入比较的前串s1:"); gets(s1);

printf("输入比较的后串s2:"); gets(s2); result=strcmp(s1,s2);//使用标准库函数比较字符串s1和s2

if(result>0) printf("s1>s2(前串大于后串)\n"); elseif(result<0) printf("s1<s2(前串小于后串)\n"); else printf("s1=s2(前串等于后串)\n");}2)有长度限制的字符串比较

程序设计中,子串指的是字符串中从某一位置开始连续的若干个字符构成的一个字符序列,对应于子串将包含子串的字符串称之为主串。一个子串也可以和主串是完全相同的,即子串由主串所有的字符构成。因为子串有可能是主串的一个连续的局部,为了在串中查找子串就必须研究比较两个字符串中从某个位置开始的有限长连续字符序列的问题。为了简单起见,假设开始位置为字符串的首字符(如需要从字符串中的其他位置开始,只需用地址的方式表示出起始点),即讨论比较两个字符串前n个字符构成的字符序列的关系。比较两个字符串前n个字符关系的与比较两个字符串关系的基本思想完全一致,判断比较结果的规则也相同,所不同的是多了一个比较的长度限制。7.2.6字符串的比较和字串的查找

例7-21

函数的原型为:int

strncompare(chars[],chart[],intn);,其功能是比较两个字符串s和t前n个字符构成的字符串的关系,比较规则如下所示,请编制函数strncompare并用相应主函数进行测试。7.2.6字符串的比较和字串的查找int

strncompare(char

s[],char

t[],intn){ inti;

for(i=0;s[i]==t[i];i++)

if(s[i]=='\0'||--n<=0) return0; returns[i]-t[i];}

在比较函数strncompare中,循环执行的条件是s[i]==t[i],即当遇到两个ASCII码值不相同的字符时循环结束,返回该位置两个字符ASCII码值之差(s[i]-t[i]);当循环条件成立时则判断是否两个字符串同时结束或则是否已经比较过了指定的字符个数,在两个字符串同时结束或则已经比较过了指定的字符个数时返回数值0表示两个字符串前n个字符(或者两个字符串)相同;当对应位置的两个字符既相同,但该位置字符不是字符串结尾符号而且规定的字符比较次数又未完成时,则取出下一对字符进行比较。7.2.6字符串的比较和字串的查找

标准函数库中提供了相应的字符串比较函数,函数的原型为:

int

strncmp(constchar*string1,constchar*string2,size_tcount);

函数的功能是:比较连个字符串string1和string2中至多前count个字符的关系,返回值确定规则为:如果string1大于string2,则返回值大于0;如果string1等于string2,返回值等于0;如果string1小于string2,返回值小于0。

例7-22

使用标准库函数比较两个字符串前n个字符。

7.2.6字符串的比较和字串的查找/*Name:ex07-22.cpp*/#include<stdio.h>#include<string.h>voidmain(){ int

strncompare(char

s[],char

t[],intn); chars1[80],s2[80];

int

len,result;

printf("输入比较的前串s1:"); gets(s1);

printf("输入比较的后串s2:"); gets(s2);

printf("输入如比较长度:");

scanf("%d",&len); result=strncmp(s1,s2,len);//使用标准库函数strncmp比较s1和s2的前len个字符

if(result>0) printf("s1>s2(前串大于后串)\n"); elseif(result<0) printf("s1<s2(前串小于后串)\n"); else printf("s1=s2(前串等于后串)\n");}3)字符串中子串的查找

在字符串中查找指定子串的基本思想是:首先在主串中查找子串的首字符,如果找到则比较主串中其后连续的若干个字符是否与参与比较的子串相同。如果相同则返回子串首字符在主串中出现的位置(序号或地址);否则在主串中向后继续查找直到在主串中再也找不到子串的首字符为止;当指定查找的子串在主串中不存在时,函数则返回-1(序号方式)或NULL(地址方式)。

例7-23

函数的原型为:int

findsubstr(chars[],chart[]);,其功能是在实现在s串中查找子串t第一次出现的起始位置,若t是s的子串返回t在s中第一次出现的下标序号,否则返回-1。编制该函数并用相应主函数进行测试。7.2.6字符串的比较和字串的查找

上面函数findsubstr中,对于字符串s和t首先调用函数search_chr(在7.2.4中介绍)在以&s[i]开始的字符串中查找t串的首字符t[0];然后在t串首字符找到的情况下调用函数strncompare(在7.2.6中介绍)比较两个字符串&s[i]和t前len(len是t串长度)个字符构成的字符序列,若比较结果为0则返回此时的i值表示子串的起始地址,当比较结果不为0时在字符串s中向后移动一个位置继续进行比较;若某一次在以&s[i]开始的字符串中查找t串的首字符t[0]的结果为-1,则表示字符串t不是字符串s的子串。

7.2.6字符串的比较和字串的查找

对于子串的查找还可以从另外一个方面去考虑,即从主串中的第一个字符开始,以后每次依次向后移动一个字符的位置,取出主串中与子串长度相等的前几个字符与子串比较。若相等则返回子串在主串中的起始位置,否则继续,直到主串查找完毕为止。若主串中不存在子串,返回-1。

例7-24

重写例7.23程序以实现上述基本思想。/*Name:ex07.24.cpp主函数和strncompare函数同例7.23*/int

findsubstr(chars[],chart[]){ int

strncompare(char

s[],char

t[],intn);

inti=0,len=strlen(t);

while(strncompare(&s[i],t,len)!=0&&s[i]!='\0') i++; returns[i]!='\0'?i:-1;}7.2.6字符串的比较和字串的查找字符串中有效字符的统计字符串的复制字符串的连接字符串中字符的查找字符串中字符的插入和删除字符串的比较和子串的查找字符串中子串的插入和删除字符串与二维字符数组7.2字符串的常用处理方法及标准库函数1)字符串中子串的插入

在字符串中插入子串基本思想和在字符串中指定位置插入字符类似,仍然是首先在字符串中找到插入位置,然后移动插入点之后的所有字符以腾出插入位置,最后进行插入操作。与插入一个字符不同的是要按欲插入的子串长度腾出足够的插入位置,也就是说,在准备插入空位时需要将字符向后移动过足够的跨距而不是一个字符位置。

例7-25

函数的原型为:voidinsertsubstr(chars[],chart[]);,其功能是实现子串插入功能,插入点为子串的首字符在主串中第一次出现的位置,若满足的要求的插入点不存在则给出相应提示信息。用相应主函数对子串插入函数进行测试。

7.2.7字符串中字串的插入和删除 上面程序的insertsubstr函数中,用变量i记住s串的结尾位置,调用字符查找函数用变量jsearch_chr查找t串首字符t[0]在串s中第一次出现的位置并将该序号赋值给变量j;在t[0]在s中存在的情况下使用表达式s[i+len-1]=s[i];从串s的结尾符号开始依次将字符向后移动插入t串所需要的长度,移动操作一直进行到移动插入点字符为止(用条件i>=j控制,如采用i>j则表示后插入);最后通过循环将字符串t的所有字符依次拷贝到所腾出的空间。

例7-26

重写例7.25程序,其中子串插入函数insertsubstr的实现中要求充分利用

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论