目录
字符分类函数
C语⾔中有⼀系列的函数是专⻔做字符分类的,也就是⼀个字符是属于什么类型的字符的。这些函数的使⽤都需要包含⼀个头⽂件是 ctype.h这些函数的使⽤⽅法⾮常类似int islower ( int c );
islower 是能够判断参数部分的 c 是否是⼩写字⺟的。通过返回值来说明是否是⼩写字⺟,如果是⼩写字⺟就返回⾮0的整数,如果不是⼩写字⺟,则返回 0。练习:写⼀个代码,将字符串中的⼩写字⺟转⼤写,其他字符不变。#include <stdio.h> #include <ctype.h> int main () { int i = 0; char str[] = "Test String.\n"; char c; while (str[i]) { c = str[i]; if (islower(c)) c -= 32; putchar(c); i++; } return 0; }
字符转换函数
C语⾔提供了2个字符转换函数:int tolower ( int c ); //将参数传进去的⼤写字⺟转⼩写 int toupper ( int c ); //将参数传进去的⼩写字⺟转⼤写
上⾯的代码,我们将⼩写转⼤写,是-32完成的效果,有了转换函数,就可以直接使⽤ tolower 函 数。#include <stdio.h> #include <ctype.h> int main () { int i = 0; char str[] = "Test String.\n"; char c; while (str[i]) { c = str[i]; if (islower(c)) c = toupper(c); putchar(c); i++; } return 0; }
strlen的使用和模拟实现
• 字符串以 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前⾯出现的字符个数(不包含 '\0' )。• 参数指向的字符串必须要以 '\0' 结束。• 注意函数的返回值为size_t,是无符号的。• strlen的使⽤需要包含头⽂件#include <stdio.h> #include <string.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的模拟实现://方法一 计数器⽅式 int my_strlen(const char* str) { int count = 0; assert(str); while (*str) { count++; str++; } return count; } //方法二 不创建临时变量计数器 int my_strlen(const char* str) { assert(str); if (*str == '\0') return 0; else return 1 + my_strlen(str + 1); } //方法三 指针-指针的⽅式 int my_strlen(char* s) { assert(str); char* p = s; while (*p != '\0' ) p++; return p - s; }
strcpy的使用和模拟实现
• 源字符串必须以 '\0' 结束。• 会将源字符串中的 '\0' 拷⻉到⽬标空间。• ⽬标空间必须⾜够⼤,以确保能存放源字符串。• ⽬标空间必须可修改。strcpy的模拟实现:char* my_strcpy(char* dest, const char* src) { char* ret = dest; assert(dest && src); while ((*dest++ = *src++)) { ; } return ret; }
strcat的使用和模拟实现
• 源字符串必须以 '\0' 结束。• ⽬标字符串中也得有 \0 ,否则没办法知道追加从哪⾥开始。• ⽬标空间必须有⾜够的⼤,能容纳下源字符串的内容。• ⽬标空间必须可修改。模拟实现strcat函数:char* my_strcat(char* dest, const char* src) { char* ret = dest; assert(dest && src); while (*dest) { dest++; } while ((*dest++ = *src++)) { ; } return ret; }
strcmp的使用和模拟实现
• 标准规定:◦ 第⼀个字符串⼤于第⼆个字符串,则返回⼤于0的数字◦ 第⼀个字符串等于第⼆个字符串,则返回0◦ 第⼀个字符串⼩于第⼆个字符串,则返回⼩于0的数字◦ 那么如何判断两个字符串? ⽐较两个字符串中对应位置上字符ASCII码值的⼤⼩。strcmp函数的模拟实现:int my_strcmp (const char* str1, const char* str2) { int ret = 0 ; assert(src && dest); while (*str1 == *str2) { if (*str1 == '\0') return 0; str1++; str2++; } return *str1 - *str2; }
strncpy的使用和模拟实现
• 拷贝num个字符从源字符串到⽬标空间。• 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。strncpy函数的模拟实现:#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <string.h> #include <assert.h> char* my_strncpy(char* str1, const char* str2, int num) { char* ret = str1; assert(str1 && str2); while (num--) { *(str1 + num) = *(str2 + num); } return str1; } int main() { char arr1[20] = "I HATE C LANGUAGE"; char arr2[] = "I LOVE"; printf("%s\n", arr1); //strncpy(arr1, arr2, 5); char* str1 = my_strncpy(arr1, arr2, 6); printf("%s\n",arr1); return 0; }
strncat的使用和模拟实现
• 将source指向字符串的前num个字符追加到destination指向的字符串末尾,再追加⼀个 \0 字 符• 如果source指向的字符串的⻓度⼩于num的时候,只会将字符串中到 \0 的内容追加到destination指向的字符串末尾。/* strncat example */ #include <stdio.h> #include <string.h> int main () { char str1[20]; char str2[20]; strcpy (str1, "To be "); strcpy (str2, "or not to be"); strncat (str1, str2, 6); printf("%s\n", str1); return 0; }
模拟实现strncat#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <string.h> #include <assert.h> char* my_strcat(char* str1, const char* str2, size_t num) { assert(str1 && str2); char* ret = str1; while (*str1 != '\0') { str1++; } while ((num--) && (*str1++ = *str2++)); return ret; } int main() { char arr1[20] = "I LOVE C "; char arr2[] = "LANGUAGEKKKKK"; printf("%s\n", arr1); //strncat(arr1, arr2, 8); //printf("%s\n", arr1); char* ret = my_strcat(arr1, arr2, 8); printf("%s\n", ret); return 0; }
strncmp的使用和模拟实现
⽐较str1和str2的前num个字符,如果相等就继续往后⽐较,最多⽐较num个字⺟,如果提前发现不⼀样,就提前结束,⼤的字符所在的字符串⼤于另外⼀个。如果num个字符都相等,就是相等返回0.
strstr的使用和模拟实现
函数返回字符串str2在字符串str1中第⼀次出现的位置。字符 串的⽐较匹配不包含 \0 字符,以 \0 作为结束标志。/* strstr example */ #include <stdio.h> #include <string.h> int main () { char str[] = "This is a simple string"; char* pch; pch = strstr (str, "simple"); strncpy (pch, "sample", 6); printf("%s\n", str); return 0; }
strstr的模拟实现:#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <string.h> #include <assert.h> char* my_strstr(const char* str1, const char* str2) { const char* s1 = NULL; const char* s2 = NULL; const char* cu = str1; assert(str1 && str2); if (*str2 == '\0') return (char*)str1; while (*cu) { s1 = cu; s2 = str2; while (*s1 == *s2) { s1++; s2++; } if (*s2 == '\0') { return (char*)cu; } cu++; } return NULL; } int main() { char arr1[] = "abbbcdef"; char arr2[] = "bbc"; //char* ret = strstr(arr1, arr2); char* ret = my_strstr(arr1, arr2); if (ret != NULL) printf("%s\n", ret); else printf("Not Find!!\n"); return 0; }
strtok的使用和模拟实现
• sep参数指向⼀个字符串,定义了⽤作分隔符的字符集合• 第⼀个参数指定⼀个字符串,它包含了0个或者多个由sep字符串中⼀个或者多个分隔符分割的标记。• strtok函数找到str中的下⼀个标记,并将其⽤ \0 结尾,返回⼀个指向这个标记的指针。(注: strtok函数会改变被操作的字符串,所以在使⽤strtok函数切分的字符串⼀般都是临时拷⻉的内容 并且可修改。)• strtok函数的第⼀个参数不为NULL ,函数将找到str中第⼀个标记,strtok函数将保存它在字符串 中的位置。• strtok函数的第⼀个参数为 NULL ,函数将在同⼀个字符串中被保存的位置开始,查找下⼀个标记。• 如果字符串中不存在更多的标记,则返回 NULL 指针。#include <stdio.h> #include <string.h> int main() { char arr[] = "10.10.1.1"; char* sep = "."; char* str = NULL; for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep)) { printf("%s\n", str); } return 0; }
strerror的使用和模拟实现
strerror函数可以把参数部分错误码对应的错误信息的字符串地址返回来。在不同的系统和C语⾔标准库的实现中都规定了⼀些错误码,⼀般是放在 errno.h 这个头⽂件中说明的,C语⾔程序启动的时候就会使⽤⼀个全⾯的变量errno来记录程序的当前错误码,只不过程序启动 的时候errno是0,表⽰没有错误,当我们在使⽤标准库中的函数的时候发⽣了某种错误,就会讲对应 的错误码,存放在errno中,⽽⼀个错误码的数字是整数很难理解是什么意思,所以每⼀个错误码都是 有对应的错误信息的。strerror函数就可以将错误对应的错误信息字符串的地址返回。#include <errno.h> #include <string.h> #include <stdio.h> //我们打印⼀下0~10这些错误码对应的信息 int main() { int i = 0; for (i = 0; i <= 10; i++) { printf("%s\n", strerror(i)); } return 0; } //在Windows11+VS2022环境下输出的结果如下: No error Operation not permitted No such file or directory No such process Interrupted function call Input/output error No such device or address Arg list too long Exec format error Bad file descriptor No child processes