个人博客网址:https://ljsblog.com
字符函数和内存函数(八)
- 求字符串长度
- strlen
- 长度不受限制的字符串函数
- strcpy
- strcat
- strcmp
- 字符串查找
- strstr
- strtok
- 字符操作
- 内存操作函数
- memcpy
- memmove
- memset
- memcmp
字符函数
求字符串长度的字符串函数
strlen
格式:
size_t strlen(const char*str)
其中size_t是无符号整型
从字符串的开头位置依次向后计数,遇见\0结束,最终计算的字符串长度不包括\0。
例:
#include <stdio.h>
#include <string.h>
int main()
{
int len=strlen("myblog");
printf("%d\n",len);//6
return 0;
}
注:strlen函数的返回类型是无符号整型(unsigned int)
例:
#include <stdio.h>
#include <string.h>
int main()
{
if(strlen("my")-strlen("myblog")>0)
//两个无符号数相减依然是无符号数
{
printf("大于零\n");
}
else
{
printf("小于等于零\n");
}
return 0;
}
//大于零
模拟实现
#include <stdio.h>
unsigned int my_strlen(const char* str)
{
int c=0;
while(*str!='\0')
{
str++;
c++;
}
return c;
}
int main()
{
int len=0;
len=my_strlen("ljsblog");//7
printf("%d\n",len);
}
长度不受限的字符串函数
strcpy
对字符串进行复制
格式
char* strcpy(char* strDestination, const char* strSource);
注:
- 源字符串必须以’\0’结束
- 目标空间必须足够大
- 目标空间可以修改
例:
#include <stdio.h>
#include <string.h>
int main()
{
char a1[]="abcdef";
//a1: 'a' 'b' 'c' 'd' 'e' 'f' '\0
char a2[]="my";
//a2: 'm' 'y' '\0'
strcpy(a1,a2);
//a1变为'm' 'y' '\0' 'd' 'e' 'f' '\0'
printf("%s\n",a1);//my
return 0;
}
模拟实现
#include <stdio.h>
char* my_strcpy(char *dest,const char *src)
{
char* cp=dest;
while( *dest++ = *src++ )
{
;
}
return cp;
}
int main()
{
char arr1[]="ljsblog";
char arr2[]="mybl";
my_strcpy(arr1,arr2);
printf("%s\n",arr1);
return 0;
}
strcat
将两个字符串连接起来,目的字符串末尾的\0会被覆盖,源字符串末尾的\0会一起被复制过去,最终的字符串只有一个\0。
格式:
char* strcat(char* strDestination, const char* strSource);
注:
- 目的空间必须足够大
- 源字符串必须以’\0’结束
- 目标空间可以修改
例:
#include <stdio.h>
#include <string.h>
int main()
{
char a1[10]="my";
//a1: 'm' 'y' '\0' '\0' '\0' '\0' '\0' '\0' '\0' '\0'
char a2[]="blog";
//a2: 'b' 'l' 'o' 'g' '\0'
strcat(a1,a2);
//a1: 'm' 'y' 'b' 'l' 'o' 'g' '\0' '\0' '\0' '\0'
printf("%s\n",a1);//myblog
return 0;
}
模拟实现
#include <stdio.h>
char* my_strcat(char *dest,const char *src)
{
char* cp=dest;
while(*dest !=0 )
{
dest++;
}
while( *dest++ = *src++ )
{
;
}
return cp;
}
int main()
{
char arr1[256]="ljs";
char arr2[]="blog";
my_strcat(arr1,arr2);
printf("%s\n",arr1);//ljsblog
return 0;
}
strcmp
对两个字符串进行比较,据ASCII编码依次比较str1和str2的每一个字符,直到出现不等的字符,或者遇到\0。
格式:
int strcmp(const char* stri1,const char* str2);
返回值:
- 返回值<0,表示str1小于str2。
- 返回值>0,表示str2小于str1。
- 返回值=0,表示str1等于str2。
例:
#include <stdio.h>
#include <string.h>
int main()
{
char* a1="abcd";
char* a2="bbcd";
int ret=strcmp(a1,a2);
printf("%d\n",ret);
//在vs编译器下返回值为-1,其他编译器结果可能有所不同
return 0;
}
模拟实现
#include <stdio.h>
int my_strcmp(const char *str1,const char *str2)
{
while(*str1 == *str2)
{
if(*str1 == 0)
{
return 0;
}
str1++;
str2++;
}
return (*str1 - *str2);
}
int main()
{
char arr1[]="ljsblog";
char arr2[]="ljmblog";
int ret=0;
ret=my_strcmp(arr1,arr2);
printf("%d\n",ret);//6
return 0;
}
长度受限的字符串函数
strncpy
把源字符串复制到目的字符串,最多复制n个字符。
当源字符串的长度小于n时,复制完字符串后,在目标的后边追加0,直到n个。
格式:
char *strncpy(char *dest, const char *src, size_t n)
例:
#include <stdio.h>
#include <string.h>
int main()
{
char a1[]="abblog";
char a2[]="my";
strncpy(a1,a2,2);
printf("%s\n",a1);//myblog
return 0;
}
strncat
把源字符串所指向的字符串的前n个字符追加到目标字符串的结尾并自动补0。
注:若次数n大于源字符串长度,将源字符串追加到目标字符串并且补0后,剩下的次数忽略不计。
例如:
char *strncat(char *dest, const char *src, size_t n)
例:
#include <stdio.h>
#include <string.h>
int main()
{
char a1[10]="my";
char a2[]="blog";
strncat(a1,a2,4);
printf("%s\n",a1);//myblog
return 0;
}
strncmp
把str1和str2进行比较,比较到出现不一样的字符或者一个字符串结束或者n个字符全部比较完。
格式:
int strncmp(const char *str1, const char *str2, size_t n)
#include <stdio.h>
#include <string.h>
int main()
{
char* a1="abcdsd";
char* a2="abcdef";
int ret=strncmp(a1,a2,4);
printf("%d\n",ret);//0
return 0;
}
字符串查找
strstr
返回在字符串str1中查找第一次出现字符串str2的位置。
如果str1中不存在str2,则返回NULL。
格式:
char *strstr(const char *str1, const char *str2)
例:
#include <stdio.h>
#include <string.h>
int main()
{
char arr1[]="ljsblogblog";
char arr2[]="bl";
char *ret=strstr(arr1,arr2);
if(ret == NULL)
{
printf("不存在\n");
}
else
{
printf("%s\n",ret);//blogblog
}
return 0;
}
模拟实现
#include <stdio.h>
char* my_strstr(char* str1,char* str2)
{
char *s1=str1;
char *s2=str2;
char *s=str1;
if(*str2==0)
{
return s1;
}
while(*s)
{
s1=s;
s2=str2;
while((*s1 != 0) && (*s2 != 0) && (*s1==*s2))
{
s1++;
s2++;
}
if(*s2==0)
{
return s;
}
s++;
}
return NULL;
}
int main()
{
char arr1[]="ljsblogblog";
char arr2[]="bl";
char *ret=my_strstr(arr1,arr2);
if(ret == NULL)
{
printf("不存在\n");
}
else
{
printf("%s\n",ret);//blogblog
}
return 0;
}
strtok
分解字符串为一组字符串,str为要分解的字符串,delim为分隔符字符(如果传入字符串,则传入的字符串中每个字符均为分割符)。
首次调用时,str指向要分解的字符串,之后的调用要把str设成NULL。
如果字符串中不存在标记或者不存在更多的标记,则返回NULL指针。
格式:
char *strtok(char *str, const char *delim)
例:
#include <stdio.h>
#include <string.h>
int main()
{
char a1[]="ab.cd#ef.gh";
char* a2=".#";
char* ret=NULL;
for(ret=strtok(a1,a2);ret!=NULL;ret=strtok(NULL,a2))
{
printf("%s\n",ret);
}
return 0;
}
/*
ab
cd
ef
gh
*/
错误信息报告
strerror
返回错误码所对应的错误信息
格式:
char *strerror(int errnum)
例:
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
FILE* pf=fopen("test.txt","r");
if(pf==NULL)
{
printf("%s\n",strerror(errno));
//errno用来存储错误代码,当库函数在执行过程中发生错误时,就会将错误码写入到errno中
}
else
{
printf("打开成功\n");
}
return 0;
}
/*
No such file or directory
*/
内存函数
memcpy
从str2复制n个字节到str1。
格式:
void *memcpy(void *str1, const void *str2, size_t n)
例:
#include <stdio.h>
#include <string.h>
int main()
{
int a1[]={1,2,3,4,5};
int a2[5]={0};
int i=0;
memcpy(a2,a1,sizeof(a1));
for(i=0;i<5;i++)
{
printf("a2[%d]=%d\n",i,a2[i]);
}
return 0;
}
/*
a2[0]=1
a2[1]=2
a2[2]=3
a2[3]=4
a2[4]=5
*/
memmove
从str2复制n个字符到str1,但与memcpy不同的是,memmove可以处理重叠内存的复制。
格式:
void *memmove(void *str1, const void *str2, size_t n)
例:
#include <stdio.h>
#include <string.h>
int main()
{
int arr[]={1,2,3,4,5,6,7,8,9,10};
int i=0;
memmove(arr+2,arr,16);
for(i=0;i<10;i++)
{
printf("arr[%d]=%d\n",i,arr[i]);
}
return 0;
}
/*
arr[0]=1
arr[1]=2
arr[2]=1
arr[3]=2
arr[4]=3
arr[5]=4
arr[6]=7
arr[7]=8
arr[8]=9
arr[9]=10
*/
memcmp
把str1和str2的前n个字节进行比较。
格式:
int memcmp(const void *str1, const void *str2, size_t n)
返回值:
- 返回值<0,表示str1小于str2。
- 返回值>0,表示str1大于str2。
- 返回值=0,表示str1等于str2。
#include <stdio.h>
#include <string.h>
int main()
{
int a1[]={1,2,3,4,5};
int a2[]={1,2,4,4,5};
int ret=memcmp(a1,a2,sizeof(a1));
printf("%d\n",ret);//-1
return 0;
}
memset
将字符c复制到参数str所指向的空间的前n个字节。
格式:
void *memset(void *str, int c, size_t n)
例:
#include <stdio.h>
#include <string.h>
int main()
{
char a[8]="myblog";
memset(a,'c',7);
printf("%s\n",a);
//ccccccc
return 0;
}