字符串函数
string.h:
常用如下函数:
strlen
strcmp
strcpy
strcat
strchr
strstr
使用字符串函数,需要#include <string.h>
1.strlen
size_t strlen(const char *s);
返回s的字符串长度(不包括结尾的0),const是保证不会修改你的字符串
int main(int argc,char const *argv[])
{
char line[]="Hello";
printf("strlen=%lu\n",strlen(line));//strlen=5
printf("sizeof=%lu\n",sizeof(line));//sizeof=6 包括了\0
return 0;
}
想要自己写一个mylen函数代替strlen
int mylen(const char *s){
int cnt=0;
int idx=0;
while(s[idx]!='\0'){
idx++;//指向下一个
cnt++;//计数器加1
//代码可简化,因为idx和cnt同时做++,简化可去掉cnt,并且直接返回idx
}
return cnt;
}
int main(int argc,char const *argv[])
{
char line[]="Hello";
printf("mylen=%lu\n",mylen(line));//mylen=5
printf("sizeof=%lu\n",sizeof(line));//sizeof=6 包括了\0
return 0;
}
2.strcmp
int strcmp(const char *s1,const char *s2);
比较两个字符串,返回:
0:s1==s2
1:s1>s2
-1:s1<s2
int main(int argc,char const *argv[])
{
char s1[]="abc";
char s2[]="abc";
printf("%d\n",strcmp(s1,s2));//0
//printf("%d\n",s1==s2); warning:array comparison always evaluates to false 警告:数组的比较永远是false
//因为这两个数组一定不会是相同的地址,当我们要比较两个数组变量的时候,用==表达的是他们是否是相同的地址
char s3[]="bbc";
printf("%d\n",strcmp(s1,s3));//-1 s1<s3 a<b
char s4[]="Abc";
printf("%d\n",strcmp(s1,s4));//1 小写字母比大写字母大
return 0;
}
想要自己写一个mycmp代替strcmp
int mycmp(const char *s1,const char *s2){
int idx=0;
while(1){
if(s1[idx]!=s2[idx]){
break;
}else if(s1[idx]=='\0'){
break;
}
idx++;
}
return s1[idx]-s2[idx];
}
int main(int argc,char const *argv[])
{
char s1[]="abc";
char s2[]="abc";
printf("%d\n",mycmp(s1,s2));//0
char s3[]="bbc";
printf("%d\n",mycmp(s1,s3));//-1
char s4[]="Abc";
printf("%d\n",mycmp(s1,s4));//32
return 0;
}
代码优化:
int mycmp(const char *s1,const char *s2){
int idx=0;
while(s1[idx]==s2[idx]&&s1[idx]!='\0'){//两者内容均不为'\0'
if(s1[idx]!=s2[idx]){//遇到不相等
break;
}else if(s1[idx]=='\0'){
break;//比较结束
}
idx++;//移向下一个
}
return s1[idx]-s2[idx];
}
int main(int argc,char const *argv[])
{
char s1[]="abc";
char s2[]="abc";
printf("%d\n",mycmp(s1,s2));//0
char s3[]="bbc";
printf("%d\n",mycmp(s1,s3));//-1
char s4[]="Abc";
printf("%d\n",mycmp(s1,s4));//32
return 0;
}
用指针优化:
int mycmp(const char *s1,const char *s2){
while(*s1==*s2&&*s1!='\0'){//两者内容均不为'\0'
s1++;
s2++;
}
return *s1-*s2;
}
int main(int argc,char const *argv[])
{
char s1[]="abc";
char s2[]="abc";
printf("%d\n",mycmp(s1,s2));//0
char s3[]="bbc";
printf("%d\n",mycmp(s1,s3));//-1
char s4[]="Abc";
printf("%d\n",mycmp(s1,s4));//32
return 0;
}
3.strcpy:
char *strcpy(char *restrict dst,const char *restrict src);
把src的字符串拷贝到dst,把第二个参数里的字符串,拷贝到第一个参数所表达的空间去
restrict表明src和dst不重叠(C99),resrrict是C99的新的关键字
注意在参数表中,第一个参数是目的,第二个参数是源
返回dst
为了能链起代码来,返回dst是为了用这种方式,让strcpy的结果,再参与其他的运算,能够再投入给其他函数的参数
经常用strcpy复制一个字符串
char dst=(char)malloc(strlen(src)+1);
strcpy(dst,src);
用自己写的mycpy函数代替strcpy
数组版本:
char* mycpy(char* dst,const char* src){
int idx=0;
while(src[idx]!=0){
dst[idx]=src[idx];
idx++;
}
dst[idx]=src[idx];
//或dst[idx]='\0'; 循环最后idx指向src的'\0'时,就退出了,还差一句dst[idx]=src[idx];没有做,因此dst里会少一个结尾'\0'
return dst;
}
int main(int argc,char const *argv[])
{
char s1[]="abc";
char s2[]="abc";
mycpy(s1,s2);
return 0;
}
指针版本:
char* mycpy(char* dst,const char* src){
char* ret=dst;
while(*src!='\0'){ // !=0可以去掉
*dst=*src;//下面两句,可以与本句合并为*dst++=*src++; 同样地,循环只剩该句,该句是赋值,就是*src的值,因此本句可以直接作为循环条件,循环变为空语句
dst++;
src++;
}
*dst='\0';
return ret;//指针版本不能return dst,因为dst已经被你一直加加加到后面去了
}
int main(int argc,char const *argv[])
{
char s1[]="abc";
char s2[]="abc";
mycpy(s1,s2);
return 0;
}
4.strcat:
char *strcat(char *restrict s1,const char *restrict s2);
把s2拷贝到s1的后面,接成一个长的字符串 dst[strlen(dst)]=src[0]
返回s1
s1必须具有足够的空间
5.strcpy和strcat都可能出现安全问题
如果目的地没有足够的空间
安全版本
char *strncpy(char *restrict dst,const char *restrict src,size_t n);
char *strncat(char *restrict s1,const char *restrict s2,size_t n);
在函数名间多了一个n,在参数表中也多了一个n
对于拷贝来说,n的意思是,你能够拷贝过去多少个字符
对于cat来说,你能用cat连上多少个字符
int strncmp(const char *s1,const char *s2,size_t n);
cmp也有带n的版本,这个版本的意思是说,判断两个字符串前n个字符是否一致
6.字符串中找字符
char *strchr(const char *s,int c);
意思是在s这个字符串里,找c第一次出现的位置,从左边开始找
char *strrchr(const char *s,int c);从右边开始找
返回NULL表示没有找到
```c
int main(int argc,char const *argv[])
{
char s[]="hello";
char *p=strchr(s,'l');
printf("%s\n",p);//llo
return 0;
}
如何让它指向第二次出现的位置呢?
int main(int argc,char const *argv[])
{
char s[]="hello";
char *p=strchr(s,'l');
p=strchr(p+1,'l');//从p+1这个位置开始的字符串里面寻找l
printf("%s\n",p);//lo
return 0;
}
想要找到这个l后,把l后面的东西,复制到另外一个字符串当中去
int main(int argc,char const *argv[])
{
char s[]="hello";
char *p=strchr(s,'l');
char *t=(char)malloc(strlen(p)+1);
strcpy(t,p);
printf("%s\n",t);//llo
free(t);
return 0;
}
若想要l前的那一段 he
int main(int argc,char const *argv[])
{
char s[]="hello";
char *p=strchr(s,'l');
char c=*p;//用变量c临时存一下*p
*p='\0';
char *t=(char)malloc(strlen(s)+1);
strcpy(t,s);
printf("%s\n",t);//he
free(t);
return 0;
}
字符串中找字符串
char *strstr(const char *s1,const char *s2);
char *strcasestr(const char *s1,const char *s2);有case指在寻找过程中忽略大小写