1、字符分类函数
C语⾔中有⼀系列的函数是专⻔做字符分类的,也就是⼀个字符是属于什么类型的字符的。
这些函数的使⽤都需要包含⼀个头⽂件是 ctype.h

在这里介绍一下islower函数,其他的非常相似。
函数原型:
1 int islower(int c);
islower 是能够判断参数部分的 c 是否是⼩写字⺟的。
通过返回值来说明是否是⼩写字⺟,如果是⼩写字⺟就返回⾮0的整数,如果不是⼩写字⺟,则返回 0。
练习:写⼀个代码,将字符串中的⼩写字⺟转⼤写,其他字符不变。

是小写返回非0,执行下面那条转大写(即ASCII码值-32)的语句。
2、字符转换函数
C语⾔提供了2个字符转换函数:
1 int tolower ( int c ); //将参数传进去的⼤写字⺟转⼩写
2 int toupper ( int c ); //将参数传进去的⼩写字⺟转⼤写
上⾯的代码,我们将⼩写转⼤写,是-32完成的效果,有了转换函数,就可以直接使⽤ toupper 函
数。

3. strlen 的使⽤和模拟实现
1 size_t strlen ( const char * str );
字符串以 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前⾯出现的字符个数(不包
含 '\0' )。
参数指向的字符串必须要以 '\0' 结束。
注意函数的返回值为 size_t,是⽆符号的( 易错 )
strlen的使⽤需要包含头⽂件<string.h>
学会strlen函数的模拟实现

两个size_t类型相减,即使得到一个负数也是一个无符号的整型。
10000000 00000000 00000000 00000011 -3的原码
11111111 11111111 11111111 11111101 -3的补码
内存中存的是补码,无符号整型直接将补码拿出来用,得到的是一个非常大的正数。
1、strlen函数的模拟实现
1、递归方式
2、计数器方式
3、指针-指针方式
4、strcpy的使用和模拟实现
函数原型:
1 char* strcpy(char * destination, const char * source );
函数作用:将源指向的C字符串复制到目标指向的数组中,包括终止的空字符(并在此时停止)。
函数使用须知:源字符串必须以 '\0' 结束。
会将源字符串中的 '\0' 拷⻉到⽬标空间。
⽬标空间必须⾜够⼤,以确保能存放源字符串。
⽬标空间必须可修改。
例:


1、strcpy的模拟实现
循环中把\0之前的字符全面放到src中,跳出循环再把\0放到src中,以此完成了strcpy的模拟实现。
也可以这样写,后置++先使用后++,先把src解引用赋给dest再++。最后要把\0赋值给dest后才停止循环。
也可以给函数设置返回值,以实现链式访问,使得代码书写更加灵活。
5. strcat 的使⽤和模拟实现
将源字符串的副本附加到目标字符串中。目标中的终止空字符将被源的第一个字符覆盖,并且在目标中两者的连接形成的新字符串的末尾包含一个空字符。
使用须知与目标:
源字符串必须以 '\0' 结束。
⽬标字符串中也得有 \0 ,否则没办法知道追加从哪⾥开始。
⽬标空间必须有⾜够的⼤,能容纳下源字符串的内容。
⽬标空间必须可修改。

翻译一下工作流程:1、找到目标字符串的结尾\0
2、从\0的位置开始追加源头字符串中的数据
3、把源头数据拷贝过去,放在\0开始向后的位置
字符串⾃⼰给⾃⼰追加,如何?
不可以,因为dest中的\0已经被覆盖了,src无法遇到\0使得循环停止,会陷入死循环。
1、strcat的模拟实现
1、找到dest指向的字符串的\0
2、进行数据的拷贝(与strcpy的模拟实现一样)
6. strcmp 的使⽤和模拟实现
这个函数开始比较每个字符串的第一个字符。如果它们彼此相等,则继续使用往下对,直到字符不同或达到终止的空字符。
标准规定:
第⼀个字符串⼤于第⼆个字符串,则返回⼤于0的数字
第⼀个字符串等于第⼆个字符串,则返回0
第⼀个字符串⼩于第⼆个字符串,则返回⼩于0的数字
那么如何判断两个字符串? ⽐较两个字符串中对应位置上字符ASCII码值的⼤⼩。
1、strcmp的模拟实现
7. strncpy 函数的使⽤
函数原型:
1 char * strncpy ( char * destination, const char * source, size_t num );
拷⻉num个字符从源字符串到⽬标空间。
如果源字符串的⻓度⼩于num,则拷⻉完源字符串之后,在⽬标的后边追加0,直到num个。
追加字符之后还会放置一个\0。
8. strncat 函数的使⽤
函数原型:
1 char * strncat ( char * destination,const char* source,size_t num);
将source指向字符串的前num个字符追加到destination指向的字符串末尾,再追加⼀个 \0 字符
如果source 指向的字符串的⻓度⼩于num的时候,只会将字符串中到 \0 的内容追加到destination指向的字符串末尾。
9. strncmp函数的使⽤
函数原型:
1 int strncmp ( const char * str1, const char * str2, size_t num );
⽐较str1和str2的前num个字符,如果相等就继续往后⽐较,最多⽐较num个字⺟,如果提前发现不⼀ 样,就提前结束,⼤的字符所在的字符串⼤于另外⼀个。如果num个字符都相等,就是相等返回0。
10. strstr 的使⽤和模拟实现
函数原型:
1 char * strstr ( const char * str1, const char * str2);
在str1中查找str2这个字符串,第一次出现的位置,如果找到了,则返回起始地址,如果找不到则返回NULL。
1、strstr的模拟实现
#include <stdio.h>char* my_strstr(const char* str1, const char* str2) {// 如果 str2 是空字符串,直接返回 str1 的起始地址if (*str2 == '\0') {return (char*)str1;}const char* s1 = NULL;const char* s2 = NULL;const char* cur = str1;while (*cur) {s1 = cur;s2 = str2;// 同时遍历 s1 和 s2,比较对应字符是否相等while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2) {s1++;s2++;}// 如果 s2 到达字符串结尾,说明找到了 str2if (*s2 == '\0') {return (char*)cur;}// 未找到,继续检查下一个位置cur++;}// 遍历完 str1 都未找到 str2,返回 NULLreturn NULL;
}
char* my_strstr(const char* str1, const char* str2)
{// cp 用于遍历 str1,从 str1 的起始位置开始char* cp = (char*)str1;char* s1, * s2;// 如果 str2 是空字符串,直接返回 str1 的起始地址if (!*str2)return((char*)str1);// 遍历 str1,直到遇到字符串结束符 '\0'while (*cp){// s1 指向当前 cp 所指向的位置s1 = cp;// s2 指向 str2 的起始位置s2 = (char*)str2;// 同时遍历 s1 和 s2,比较对应字符是否相等// 只要 s1、s2 都未到字符串结尾且对应字符相等,就继续比较while (*s1 && *s2 && !(*s1 - *s2))s1++, s2++;// 如果 s2 到达字符串结尾,说明找到了 str2if (!*s2)return(cp);// 如果未找到,cp 指向下一个字符,继续查找cp++;}// 如果遍历完 str1 都未找到 str2,返回 NULLreturn(NULL);
}