一. 字符分类函数
C语⾔中有⼀系列的函数是专⻔做字符分类的,也就是⼀个字符是属于什么类型的字符的。
这些函数的使⽤都需要包含⼀个头⽂件是 ctype.h
这些函数的使⽤⽅法⾮常类似,我们就讲解⼀个函数的事情,其他的⾮常类似:
int islower ( int c );
islower 是能够判断参数部分的c是否是⼩写字⺟的。
通过返回值来说明是否是⼩写字⺟,如果是⼩写字⺟就返回⾮0的整数,如果不是⼩写字⺟,则返回 0。
1.1 练习:将字符串小写转换成大写
思路:小写字母ASCII值大于大写字母ASCII值32.
#include <stdio.h> #include <ctype.h> int main() { int i = 0; char str[] = "i am a student."; while (str[i]) { if (islower(str[i])) str[i] = str[i] - 32; i++; } printf("%s", str); return 0; }
输出:
二、 字符转换函数
C语⾔提供了2个字符转换函数:
int tolower ( int c ); //将参数传进去的大写字⺟转小写 int toupper ( int c ); //将参数传进去的小写字⺟转大写
2.1 练习:将字符串小写转换成大写
思路:
上面的代码,我们将小写转大写,是-32完成的效果,有了转换函数,就可以直接使⽤ toupper 函数。
#include <stdio.h> #include <ctype.h> int main() { int i = 0; char str[] = "i am a student."; while (str[i]) { if (islower(str[i])) str[i] = toupper(str[i]); i++; } printf("%s", str); return 0; return 0; }
三. strlen的使用和模拟实现
size_t strlen ( const char * str );
3.1 strlen的注意事项
• 字符串以 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前⾯出现的字符个数(不包
含 '\0' )。
• 参数指向的字符串必须要以 '\0' 结束。
• 注意函数的返回值为size_t,是无符号的( 易错考点 )
易错考点:
#include <stdio.h> int main() { const char* str1 = "abcdef"; const char* str2 = "bbb"; if (strlen(str2) - strlen(str1) > 0) { printf("str2>str1\n"); } else { printf("srt1>str2\n"); } return 0; }
输出:
解析: strlen(str2) - strlen(str1) > 0,strlen的返回类型是无符号整型,无符号整型-无符号整型还是无符号整型,-3的补码当成正数看是一个非常大的正数
3.2 strlen函数的模拟实现
方式1:
//计数器⽅式 size_t my_strlen(const char * str) { int count = 0; assert(str); while(*str) { count++; str++; } return count; }
方式2:
//指针-指针的⽅式==中间元素个数 size_t my_strlen(char *s) { assert(str);//保证指针的安全性 char *p = s; while(*p != ‘\0’ ) { p++; } return p-s; } 方式3: //递归 size_t my_strlen(const char * str) { assert(str); if(*str == '\0') return 0; else return 1+my_strlen(str+1); }
值得注意的是return 1+my_strlen(str+1);这里的str+1不能改成str++,因为str++是先用后++,每次都是传str的地址,导致死循环。
四. strcpy的使用和模拟实现
char* strcpy(char * destination, const char * source );
Copies the C string pointed by source into the array pointed by destination, including the
terminating null character (and stopping at that point).
将source指向的字符串copy到destination指向的空间,包括源字符串的‘0’也会被copy进去。
返回值是目标空间的起始地址。
4.1 strcpy的注意事项
• 源字符串必须以 '\0' 结束。
• 会将源字符串中的 '\0' 拷⻉到⽬标空间。
• ⽬标空间必须⾜够⼤,以确保能存放源字符串。
• ⽬标空间必须可变。
4.2 strcpy的模拟实现
char *my_strcpy(char *dest, const char*src) { char *ret = dest; assert(dest != NULL); assert(src != NULL); while((*dest++ = *src++)) { ; } return ret; }
五. strcat的使用和模拟实现
char * strcat(char*destination,const char*source)
Appends a copy of the source string to the destination string. The terminating null character
in destination is overwritten by the first character of source, and a null-character is included
at the end of the new string formed by the concatenation of both in destination.
源字符串追加copy到目标字符串,源字符串的第一个字符覆盖目标字符串的最后'\0'字符,追加copy内容一直包括源字符串的'\0'字符。
5.1 strcat的注意事项
• 源字符串必须以 '\0' 结束。
• ⽬标字符串中也得有 ‘0’ ,否则没办法知道追加从哪⾥开始。
• ⽬标空间必须有⾜够的⼤,能容纳下源字符串的内容。
• ⽬标空间必须可修改。
问题:自己追加拼接自己可以吗?
int main() { char s[20] = "hellow"; char*p=strcat(s, s); printf("%s", s); return 0; }
输出:
答案:不可以!因为追加拼接的时候会覆盖s的‘\0’,导致会无限 拼接,会使目标数组越界访问。
5.2 strcat的模拟实现
char *my_strcat(char *dest, const char*src) { char *ret = dest; assert(dest != NULL); assert(src != NULL); while(*dest) { dest++; } while((*dest++ = *src++)) { ; } return ret; }
六. strcmp 的使用和模拟实现
int strcmp(const char*str1,const char*str2)
This function starts comparing the first character of each string. If they are equal to each
other, it continues with the following pairs until the characters differ or until a terminating
null-character is reached.
函数比较俩个字符串大小
函数开始比较俩个字符串第一个字符,若俩个字符相等,按顺序依次比较接下来对应位置字符,直到字符不同或者到‘\0’字符结束。
• 标准规定:
◦ 第⼀个字符串⼤于第⼆个字符串,则返回⼤于0的数字
◦ 第⼀个字符串等于第⼆个字符串,则返回0
◦ 第⼀个字符串⼩于第⼆个字符串,则返回⼩于0的数字
◦ 那么如何判断两个字符串? 比较两个字符串中对应位置上字符ASCII码值的大小。
6.1 strcmp函数的模拟实现
int my_strcmp (const char * str1, const char * str2) { int ret = 0 ; assert(src != NULL); assert(dest != NULL); while(*str1 == *str2) { if(*str1 == '\0') return 0; str1++; str2++; } return *str1-*str2; }
七. strncpy 函数的使用和模拟实现
char * strncpy ( char* destination, const char * source, size_t num );
• 拷⻉num个字符从源字符串到⽬标空间。
• 如果源字符串的⻓度⼩于num,则拷⻉完源字符串之后,在⽬标的后边追加0,直到num个。
7.1 strncpy的模拟实现
#include <stdio.h> #include <assert.h> char* my_strncpy(char* dest, const char* src, size_t num) { char* ret = dest; assert(dest); assert(src); int i = 0; while (i < num && *src != '\0') { *dest++ = *src++; i++; } if (i == num) { return ret; } else { while (i < num) { *dest = '\0'; dest++; i++; } return ret; } } int main() { char arr1[10] = "xxxxxxxxx"; char arr2[] = "ab"; char* ret = my_strncpy(arr1, arr2, 5); printf("%s\n", ret); return 0; }
通过调试发现,少于num的位置用'\0'补齐。