目录
一.求字符串长度
二.长度不受限制的字符串函数
1.strcpy函数
2.strcat函数
3.strcmp函数
三.长度受限制的字符串函数
1.strncpy函数
2.strncat函数
3.strncmp函数
四.字符串查找
1.strstr函数
2.strtok函数
3.strerror函数
五.字符操作
1.字符分类
2.字符转换
六.字符操作函数
1.memcpy函数
2.memmove函数
3.memcmp函数
4.memset函数
一.求字符串长度
strlen函数
头文件:string.h
size_t strlen(const char* str) //求字符串长度
注:
- 字符串以 ‘\0’ 作为结束标志,strlen 返回的是在字符串中 ‘\0’ 前面出现的字符个数
- 参数指向的字符串必须以 ‘\0’ 结束
- 函数的返回值为 size_t ,无符号(unsigned)
用法演示:
#include <stdio.h>
#include <string.h>
int main()
{
int len = strlen("abcdef");
printf("%d\n", len);
return 0;
}
运行结果:6
二.长度不受限制的字符串函数
1.strcpy函数
头文件:string.h
char *strcpy(char *dest, const char *src); //字符串拷贝
//dest为目标空间,src为要拷贝的源字符串
注:
- 字符串拷贝,将含有 ‘\0’ 的字符串复制到另一个地址空间,返回值的类型为 char*
- 源字符串 src 必须以 ‘\0’ 结束
- 会将源字符串 src 中的 ‘\0’ 一同拷贝到目标空间 dest
- 目标空间必须足够大,以确保能够存放源字符串 dest (下面讲 strncmp 的时候演示)
- 目标空间必须可变,即目标空间 dest 不可以被 const 声明
用法演示:
#include <stdio.h>
#include <string.h>
int main()
{
char arr1[] = "abcdefghi";
char arr2[] = "123";
printf("拷贝前:%s\n", arr1);
strcpy(arr1, arr2); //字符串拷贝(目标空间,源字符串)
printf("拷贝后:%s\n", arr1);
return 0;
}
运行结果:abcdefghi 123
2.strcat函数
头文件:string.h
char *strcat(char *dest, const char *src) //字符串拼接
//dest为目标字符串,src为要拼接的源字符串
注:
- 将 src 所指向的字符串复制到 dest 所指向的字符串后面(删除 *dest 原来末尾的 ‘\0’ )
- 源字符串 src 必须以 ‘\0’ 结束
- 会将源字符串 src 中的 ‘\0’ 一同拷贝到目标空间 dest ,并删除 *dest 原来末尾的 ‘\0’
- 目标空间必须足够大,以确保能够存放源字符串 dest
- 目标空间必须可变,即目标空间 dest 不可以被 const 声明
用法演示:
#include <stdio.h>
#include <string.h>
int main()
{
char arr1[30] = "hello";
char arr2[] = "world";
strcat(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
运行结果:helloworld
3.strcmp函数
头文件:string.h
int strcmp(const char *str1, const char *str2) //比较字符串的大小
用于比较两个字符串并根据比较结果返回整数, 两个字符串自左向右逐个字符相比,按照 ASCII值 大小相比较,从第一对字符开始比,如果相等则比下一对,直到出现不同的字符或遇 ‘\0’ 才停止。对比规则如下:
第一个字符串>第二个字符串 返回正数
第一个字符串=第二个字符串 返回0
第一个字符串<第二个字符串 返回负数
用法演示:
#include <stdio.h>
#include <string.h>
int main()
{
char *p1 = "abcdef";
char *p2 = "aqwer";
int ret = strcmp(p1, p2); // p1和p2比
printf("%d\n", ret);
return 0;
}
运行结果:-1(负数)
三.长度受限制的字符串函数
1.strncpy函数
头文件:string.h
char *strncpy(char *dest, const char *src, size_t count) //指定长度的字符串拷贝
注:
- 从源字符串中拷贝 n 个字符到目标空间
- 如果源字符串的长度小于 n,则拷贝完源字符串之后,在目标的后面追加 '\0',填充至 n 个
- dest 和 src 不应该重叠(重叠时可以用更安全的 memmove 替代)
- 目标空间必须足够大,以确保能够存放源字符串 dest
- 目标空间必须可变,即目标空间 dest 不可以被 const 声明
用法演示:
#include <stdio.h>
#include <string.h>
int main()
{
char arr1[5] = "abc";
char arr2[] = "hello world";
strncpy(arr1, arr2, 4); //从arr2中拷贝4个到arr1
printf("%s\n", arr1);
return 0;
}
运行结果:hell
2.strncat函数
头文件: string.h
char *strncat(char *dest, const char *src, size_t count) //指定长度的字符串追加
注:
- 追加 n 个字符到目标空间
- 如果源字符串的长度小于 n,则只复制 ‘\0’ 之前的内容。
用法演示:
#include <stdio.h>
#include <string.h>
int main()
{
char arr1[30] = "hello";
char arr2[] = "world";
strncat(arr1, arr2, 3); //从arr2中取3个追加到arr1中
printf("%s\n", arr1);
return 0;
}
运行结果:hellowor
3.strncmp函数
头文件: string.h
int strncpy(const char *str1, const char *str2, size_t count) //指定长度的字符串比较
比较到出现另个字符不一样或者一个字符串结束或者 n 个字符全部比较完。
( 除了指定长度n,比较方式和 strcmp 一样 )
用法演示:
#include <stdio.h>
#include <string.h>
int main()
{
const char* p1 = "abczdef";
const char* p2 = "abcqwer";
int ret = strncmp(p1, p2, 1); //int ret = strcmp(p1, p2);
int ret1 = strncmp(p1, p2, 4);
printf("%d %d\n", ret, ret1);
return 0;
}
运行结果:0 1
四.字符串查找
1.strstr函数
头文件: string.h
char *strstr(const char str2,const char *str1) //查找子串
返回字符串中首次出现子串的地址。若 str2 是 str1 的子串,则返回 str2 在 str1 中首次出现的地址。如果 str2 不是 str1 的子串,则返回 NULL 。
用法演示:
#include <stdio.h>
#include <string.h>
int main()
{
char* p1 = "abcdef";
char* p2 = "def";
char* p3 = "deg";
char* ret1 = strstr(p1, p2); // 判断p2是否是p1的子串
char* res2 = strstr(p1, p3);
printf("%s\n", ret1);
printf("%s\n", ret2);
return 0;
}
运行结果:def null
2.strtok函数
头文件: string.h
char *strtok(char *str, const char *sep) //切分字符串
- sep参数是个字符串,定义了用作分隔符的字符集合
- 第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记
- strtok函数找到str中的下一个标记,并将其用 ‘\0’ 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
- strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
- strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
- 如果字符串中不存在更多的标记,则返回 NULL 指针。
用法演示:切分ip地址
//切分ip地址
#include <stdio.h>
#include <string.h>
int main()
{
char ip[] = "192.168.0.1";
char* ret = strtok(ip, ".");
printf("%s\n", ret);
ret = strtok(NULL, ".");
printf("%s\n", ret);
ret = strtok(NULL, ".");
printf("%s\n", ret);
ret = strtok(NULL, ".");
printf("%s\n", ret);
return 0;
}
运行结果:
用法演示:切分邮箱地址
//切分邮箱地址
#include <stdio.h>
#include <string.h>
int main()
{
char arr[] = "1300300100@qq.com";
printf("原字符串: %s\n", arr);
const char* sep = "@."; // 创建sep
char arr1[30];
char* ret = NULL;
strcpy(arr1, arr); // 将数据拷贝一份,保留arr数组的内容
// 分行打印切割内容
for (ret = strtok(arr, sep); ret != NULL; ret = strtok(NULL, sep)) {
printf("%s\n", ret);
}
printf("保留的原内容:%s\n", arr1); // 保存的arr数组的内容
printf("分割后原字符串被破坏: %s\n", arr); // 分割后原字符串保留第一个分割符前的字符
return 0;
}
运行结果:
3.strerror函数
头文件: string.h
char * strerror ( int errnum )
返回错误码,返回错误码所对应的错误信息
错误码 错误信息 0 - No error 1 - Operation not permitted 2 - No such file or directory ...
用法演示:
#include <string.h>
#include <stdio.h>
#include <errno.h>
int main()
{
//errno 是一个全局的错误码变量
//当c语言的库函数在执行过程中,发生了错误,
//就会把对应的错误码赋值到errno中
char* str = strerror(errno);
printf("%s\n", str);
return 0;
}
运行结果:No error
关于errno:头文件:errno.h
errno 是记录系统的最后一次错误代码,返回一个int 型的值,对应strerror的错误码
五.字符操作
1.字符分类
头文件: ctype.h
函数 | 如果他的参数符合下列条件就返回真 |
iscntrl | 任何控制字符 |
isspace | 空白字符:空格‘ ’,换页‘\f’,换行'\n',回车‘\r’,制表符'\t'或者垂直制表符'\v' |
isdigit | 十进制数字 0~9 |
isxdigit | 十六进制数字,包括所有十进制数字,小写字母a~f,大写字母A~F |
islower | 小写字母a~z |
isupper | 大写字母A~Z |
isalpha | 字母a~z或A~Z |
isalnum | 字母或者数字,a~z,A~Z,0~9 |
ispunct | 标点符号,任何不属于数字或者字母的图形字符(可打印) |
isgraph | 任何图形字符 |
isprint | 任何可打印字符,包括图形字符和空白字符 |
用法演示:islower
#include <stdio.h>
#include <ctype.h>
int main()
{
char ch1 = 'a';
int ret = islower(ch1); // 判断ch1是否为小写
printf("%d\n", ret);
char ch2 = 'B';
int res = islower(ch2); // 判断ch2是否为小写
printf("%d\n", res);
return 0;
}
运行结果:2(非0为真,表示小写) 0(假,表示大写)
2.字符转换
头文件:ctype.h
int tolower ( int c );
int toupper ( int c );
用法演示:tolower(大写转为小写)
int main()
{
char ch = tolower('Q'); // 大写转小写
putchar(ch);
return 0;
}
运行结果:q
用法演示:toupper(小写转为大写)
int main()
{
char ch = toupper('q'); // 小写转大写
putchar(ch);
return 0;
}
运行结果:Q
六.字符操作函数
1.memcpy函数
头文件: string.h
void *memcpy(void *dest, const void *src, size_t count)
//src源内存地址,dest目标内存地址,count字节数
- 从源内存地址 src 的起始位置开始拷贝 n 个字节到目标内存地址 dest 中
- memcpy 没有刹车,这个函数遇到 ‘\0’ 并不会停下来
- 如果 src 和 dest 有任何的重叠,复制的结果都是未定义的
用法演示:
#include <stdio.h>
#include <string.h>
int main()
{
int arr1[] = {1, 2, 3, 4, 5};
int arr2[5] = {0};
memcpy(arr2, arr1, sizeof(arr1));
// 打印 arr2 的内容
int i = 0;
for(i=0; i<5; i++) {
printf("%d ", arr2[i]);
}
return 0;
}
运行结果:1 2 3 4 5
2.memmove函数
头文件: string.h
void *memmove(void *dest, const void *src, size_t count)
- 用于拷贝字节,如果目标区域和源区域有重叠时,memmove 能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,但复制后源内容会被更改。
- 和 memcpy 的差别就是 memmove 函数处理的源内存块和目标内存块时可以重叠的
- 如果原空间和目标空间出现重叠,应使用 memmove 函数处理
用法演示:
#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, 20);
for(i=0; i<10; i++) {
printf("%d ", arr[i]);
}
return 0;
}
运行结果:1 2 1 2 3 4 5 8 9 10
3.memcmp函数
头文件: string.h
int memcmp(const void *ptr1, const void *ptr2, size_t num)
比较 ptr1 和 ptr2 指针开始的 n 个字节,按字节比较
- ptr1>ptr2 返回正数
- ptr1=ptr2 返回 0
- ptr1<ptr2 返回负数
memcmp 不同于 strcmp,memcmp 遇到 ‘\0’ 不会停止比较
用法演示:
#include <stdio.h>
#include <string.h>
int main()
{
float arr1[] = {1.0, 2.0, 3.0, 4.0};
float arr2[] = {1.0, 3.0};
int ret = memcmp(arr1, arr2, 8); // arr1是否比arr2大,比较8个字节
printf("%d\n", ret);
return 0;
}
运行结果:-1(说明arr1的前八字节小于arr2的前八字节)
4.memset函数
头文件: string.h
void *memset(void *ptr, int value, size_t num)
- 将某一块内存中的内容全部设置为指定的值,通常为新申请内存做初始化工作。
- memset 是以字节为单位设置内存的
用法演示:把整型数组前20个字节设置为1
#include <stdio.h>
#include <string.h>
int main()
{
// 40
int arr[10] = {0};
memset(arr, 1, 20); // 将前20个字节全部设置为1
return 0;
}
运行结果:
本文到此结束,码文不易,还请多多支持哦!