本章向大家介绍一些常用的与字符串有关的或是一些固定的内存函数,模拟实现一部分函数,帮助大家理解更透彻。
目录
strlen 求字符串长度
size_t strlen ( const char * str );
对于strlen有几点需要注意:
1.字符串将 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ )。
2.参数指向的字符串必须要以 ‘\0’ 结束。
3.注意函数的返回值为size_t,是无符号的
了解了strlen函数的机制,我们在vs上上机模拟实现一下strlen函数:
strcpy 字符串拷贝
char* strcpy(char * destination, const char * source );
strcpy的函数参数一个是指针指向目标字符串,另一个是指针指向被复制的字符串的,这里用const修饰,避免修改掉被拷贝的字符串 函数的返回类型是char *类型。
strcpy函数当然也有它需要满足的条件:
1.源字符串必须以 ‘\0’ 结束。
2.会将源字符串中的 ‘\0’ 拷贝到目标空间。
3.目标空间必须足够大,以确保能存放源字符串。
4.目标空间必须可变。
通过函数参数的类型,以及条件,我们可以看出strcpy函数在调用之后,会将一个字符串复制到另一块空间地址,‘\0’是停止拷贝的终止条件,同时也会将 ‘\0’ 也复制到目标空间。我们在vs上模拟实现:
strcat 追加字符串函数
char* strcat ( char* destination, const char* source );
strcat函数的两个参数第一个 参数是char类型指针,指向目标字符串,第二个指针也是char类型并指向源字符串(const用法与strcpy相同)
那么它所需满足的条件即是:
- 源字符串必须以 ‘\0’ 结束。
- 目标空间必须有足够的大,能容纳下源字符串的内容。
- 目标空间必须可修改。
我们发现strcat的实现模式是将src中的所有字符(连同最后的’\0’)加到源字符串中第一个‘\0’的位置。
了解了实现模式,我们上机模拟实现
既然是追加字符串,那当字符串自己给自己追加时候呢?
当字符串自己给自己追加时,相当于自己既是目标又是源头,那当把第一个字符在后面复制时,\0也随之发生变化,导致永远追不到\0,所以会导致死循环,导致越界,所以最好不要自己给自己追加。
strcmp 字符串比较函数
int strcmp (const char * str1, const char * str2 );
字符串比较函数strcmp的两个参数不用多说,一定就是要比较的两个字符串。它的比较过程:
我们首先了解一下它的规则
标准规定:
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字
我们再上机模拟一下
我们已经学习了四个内存函数,我们可以发现他们都非常关注\0,并不关注操作几个字符,我们称他们为长度不受限制的字符串函数,还有几个长度受限制的字符串函数(strncpy
,strncat,strncmp),这些函数与我们上面讲的几个函数实现一样,只不过有了操作几个字数的限制,在这里就不详细介绍,有机会大家可以去查阅资料学习。
strstr 字符串中找一个字符串
char * strstr ( const char* str1, const char* str2);
该函数的两个参数同样都是字符串指针,第一个参数指向待查找的字符串,第二个参数指向要查找的子字符串,实现模式就是找str2这个字符串,在str1中第一次出现的位置,如果找不到,返回空指针
我们来模拟实现它:
strtok 字符分割函数
char * strtok ( char * str, const char * sep )
strtok函数的实现过程:
该函数的两个参数 str是需要分割的字符串,sep是用作分隔符的字符字符串,第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。 strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改 变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。) strtok函数的第一个参数不为空指针 ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。 strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。 如果字符串中不存在更多的标记,则返回 NULL 指针。
由于这个函数我们用的不太频繁,所以这里省略模拟实现过程
strerror
char * strerror(int errnum)
strerror函数的作用就是得到指向错误消息字符串的指针
库函数在执行时,发生了错位,会将一个错误码存放在error这个变量中,error,我们将1-10所表示的错误信息打印在屏幕上看一下
字符分类函数
在c语言中还有一系列的字符分类函数,我们需要了解一下
函数 | 如果他的参数符合下列条件就返回真 |
---|---|
iscntrl | 任何控制字符 |
isspace | 空白字符:空格‘ ’,换页‘\f’,换行’\n’,回车‘\r’,制表符’\t’或者垂直制表符’\v’ |
isdigit | 十进制数字 0~9 |
isxdigit | 十六进制数字,包括所有十进制数字,小写字母af,大写字母AF |
islower | 小写字母a~z |
isupper | 大写字母A~Z |
isalpha | 字母az或AZ |
isalnum | 字母或者数字,az,AZ,0~9 |
ispunct | 标点符号,任何不属于数字或者字母的图形字符(可打印) |
isgraph | 任何图形字符 |
isprint | 任何可打印字符,包括图形字符和空白字符 |
memcpy 内存拷贝函数
void* memcpy ( void* destination, const void* source, size_t num );
memcpy函数有三个参数,第一个是目标地址,第二个是源地址,第三个是需要操作的数据长度。
它所需的条件是:
1.函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
2.这个函数在遇到 ‘\0’ 的时候并不会停下来。
3.如果source和destination有任何的重叠,复制的结果都是未定义的。
通过memcpy函数的条件我们知道,这个函数是用来处理不重叠的内存拷贝。
我们上机模拟实现:
知道了memcpy函数是无法处理源空间与目标空间重叠时的情况的,那当我们遇到这种情况时,就可以使用memmove函数:
memmove
void * memmove ( void * dest, const void * src, size_t num );
memmove函数也有三个指针,dest是目标内存区的指针。第二个参数src 是源内存区的指针。最后一个num 是要复制的字节的数量。
它和和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。我们上机模拟实现:
memcmp 内存比较函数
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
memcmp函数的功能就是比较从ptr1和ptr2指针开始的num个字节,当返回值<0时,证明在两个内存块中不匹配的第一个字节在 ptr1> 中的值低于在 ptr2 中的值(如果计算为无符号 char
值)返回值=0时两个内存块的内容相等,返回值>0说明在两个内存块中不匹配的第一个字节在 ptr1 中的值大于在 ptr2> 中的值(如果计算为无符号字符值
memcmp函数模拟实现过程这里也省略,但是注意它与其他函数的区别,memcmp函数是以字节为单位设置的
在c语言中还有很多很多的库函数等着我们去学习,本章只是一小部分比较常用的库函数集合
看到这里本章就结束了伟大的程序员辛苦了