字符函数和内存函数(八)


字符函数和内存函数(八)

  • 求字符串长度
    • strlen
  • 长度不受限制的字符串函数
    • strcpy
    • strcat
    • strcmp
  • 字符串查找
    • strstr
    • strtok
  • 字符操作
  • 内存操作函数
    • memcpy
    • memmove
    • memset
    • memcmp

字符函数

求字符串长度的字符串函数

strlen

格式
size_t strlen(const char*str)
其中size_t是无符号整型
从字符串的开头位置依次向后计数,遇见\0结束,最终计算的字符串长度不包括\0。
例:

1
2
3
4
5
6
7
8
#include <stdio.h>
#include <string.h>
int main()
{
int len=strlen("myblog");
printf("%d\n",len);//6
return 0;
}

注:strlen函数的返回类型是无符号整型(unsigned int)
例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <string.h>
int main()
{
if(strlen("my")-strlen("myblog")>0)
//两个无符号数相减依然是无符号数
{
printf("大于零\n");
}
else
{
printf("小于等于零\n");
}
return 0;
}
//大于零
模拟实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#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’结束
  • 目标空间必须足够大
  • 目标空间可以修改

例:

1
2
3
4
5
6
7
8
9
10
11
12
13
#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;
}
模拟实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#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’结束
  • 目标空间可以修改

例:

1
2
3
4
5
6
7
8
9
10
11
12
13
#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;
}
模拟实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#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。

例:

1
2
3
4
5
6
7
8
9
10
11
#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;
}
模拟实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#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)
例:

1
2
3
4
5
6
7
8
9
10
#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)
例:

1
2
3
4
5
6
7
8
9
10
#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)

1
2
3
4
5
6
7
8
9
10
#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)
例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#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;
}
模拟实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#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)
例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#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)
例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#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)
例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#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)
例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#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。
1
2
3
4
5
6
7
8
9
10
#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)
例:

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
#include <string.h>
int main()
{
char a[8]="myblog";
memset(a,'c',7);
printf("%s\n",a);
//ccccccc
return 0;
}

Author: ljs
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source ljs !
评论
  TOC