提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
由于字符串应用广泛,为方便用户对字符串的处理,C语言库函数中除了前面用到的库函数gets与puts之外,还提供了一些常用的库函数,其函数原型说明在string.h中。下面介绍一些最常用的字符串库函数。
头文件:string.h
函数原型:char * strcpy ( char * dest,const char * src )
调用格式:strcpy(dest,src)
功能:字符串复制
参数:src为源串的起始地址,dest为目标串的起始地址
返回值:目标串的起始地址
函数实现
char *strcpy(char *strDest, const char *strScr)
{
char *address=strDest;
assert((strDest != NULL) && (strScr != NULL));
while(*strScr) //是while(*strScr != ’/0’)的简化形式;
{
*strDest++ = *strScr++;
}
*strDest = '/0'; //当strScr字符串长度小于原strDest字符串长度
return address; //时,如果没有改语句,就会出错了。
}
由于数组不能进行整体赋值,所以不能直接使用赋值语句来实现拷贝(或赋值)。下面两个赋值语句是非法的:
char dest[10],src[10]="program";
dest=src;
dest="program";
示例代码如下:
#include
#include
#define N 50
int main()
{
char dest[N];
char src[]="welcome";
strcpy(dest, src);
printf("dest:%s src:%s\n", dest, src);
return 0;
}
程序执行结果如下:
dest:welcome src:welcome
在使用strcpy函数时,需要注意,目标数组应该有足够的空间存储源串。注意,字符串拷贝时,字符串src中的’\0’也一起拷贝。
src拷贝给的dest是,dest的长度(Ldes)大于src长度(Lsrc),dest前面0~Lsrc-1为scr字符串,Lsrc为”\0",Lsrc后与原来dest保持不变。
示例代码
#include
#include
int main(void)
{
char dest[6] = "123aaa";
char src[] = "abc";
printf("dest:%s",strcpy(dest,src));
printf("\n");
printf("dest`s ascii= ");
for(int i=0;i<6;i++){
printf("%d ",dest[i]);
}
printf("\n");
printf("len=%d",sizeof(dest)/sizeof(char));
return 0;
}
结果
dest:abc
dest`s ascii= 97 98 99 0 97 97
len=6
头文件:string.h
函数原型:char * strcat(char * dest,const char * src)
调用格式:strcat (dest , src)
功能:把字符串src连接到字符串dest的后面
参数:src为源串的起始地址,dest为目标串的起始地址
返回值:目标串的起始地址
函数实现
char *strcat(char *strDest, const char *strScr) //将源字符串加const,表明其为输入参数
{
char * address = strDest; //该语句若放在assert之后,编译出错
assert((strDest != NULL) && (strScr != NULL)); //对源地址和目的地址加非0断言
while(*strDest) //是while(*strDest!=’/0’)的简化形式
{ //若使用while(*strDest++),则会出错,因为++是不受循环
strDest++; //约束的。所以要在循环体内++;因为要是*strDest最后指
} //向该字符串的结束标志’/0’。
while(*strDest++ = *strScr++)
{
NULL; //该循环条件内可以用++,
} //此处可以加语句*strDest=’/0’;有无必要?
return address; //为了实现链式操作,将目的地址返回
}
示例程序如下:
#include
#include
#define N 50
int main ()
{
char dest[N]="welcome";
char src="beijing";
strcat(dest, src);
printf("dest:%s src:%s \n", dest, src);
return O;
}
程序执行结果如下:
dest : welcome beijing src:beijing
在使用strcat函数时,需要注意,目标数组应该有足够的空间,连接源串。注意,目标字符串’\0’被删除,然后连接源串。
头文件;string.h
函数原型:int strcmp(const char * str1,const char * str2)
调用格式:strcmp(str1,str2)
功能:按照ASCII码顺序比较字符串s1和字符串s2的大小。
参数:str1、str2为字符串起始地址。
返回值:比较结果。
字符串1=字符串2,返回值=0;
字符串1>字符串2,返回值>0;
字符串1<字符串2,返回值<0。
函数原型
int strcmp (const char *str1,const char *str2)
{
int len = 0;
assert((str1 != '/0') && (str2 != '/0'));
while(*str1 && *str2 && (*str1 == *str2))
{
str1++;
str2++;
}
return *str1-*str2;
}
示例程序如下
#include
#include
#define N 50
int main()
{
int t;
char str1[N];
char str2[N];
printf(">");
scanf("%s%s",str1,str2);
t=strcmp(str1,str2);
if(t==0) printf("str1=str2\n");
else if(t>0) printf("str1>str2\n");
else printf("str1);
return O;
}
>abcde
fghij
str1<str2
头文件:string.h
函数原型:size _t strlen(const char * str)
调用格式:strlen(字符串)
功能:求字符串的长度(不含字符串结束标志‘\0’)
参数:str为字符串
返回值:字符串的长度(不含字符串结束标志‘\0’)。
函数原型
int strlen(const char *str)
{
int len = 0;
assert(str != NULL);
while(*str++)
{
len++;
}
return len;
}
示例程序如下:
#include
#include
#define N 50
int main()
{
int len;
char str[N];
printf(">");
scanf("%s",str);
len=strlen(str);
printf("len=%d\n",len);
return 0;
}
程序执行结果如下:
>abcde
len=5
头文件:string.h
函数原型:char * strtok(char* dest,const char * delim);
调用格式:strtok(dest,delim)
功能:将字符串分隔成一个个片断
参数:dest为要分解的字符串,delim为分隔符字符串
返回值:分解出的字符串的地址
当strtok在参数s的字符串中发现delim中包含的分隔符时,则会将该字符串改为“\0”字符。在第一次调用时,strtok必须给予参数s字符串,往后的调用,则将参数s设置为NULL。每次调用成功则返回指向被分割出片段的指针。
示例程序如下:
#include
#include
int main(void)
{
char s[] = "192.168.11.22";
char *delim= ".";
char *p = strtok(s, c);
while (p != NULL) {
printf("%s\n", p);
p = strtok(NULL, c);
}
return 0;
}
返回 strDest 的原始值使函数能够支持链式表达式,增加了函数的“附加值”。同样功能的函数,如果能合理地提高的可用性,自然就更加理想。
链式表达式的形式如:
int iLength=strlen(strcpy(strA,strB));
又如:
char * strA=strcpy(new char[10],strB);
返回strSrc的原始值是错误的。
其一,源字符串肯定是已知的,返回它没有意义。
其二,不能支持形如第二例的表达式。
其三,为了保护源字符串,形参用 const 限定 strSrc 所指的内容,把const char * 作为 char * 返回,类型不符,编译报错。