C语言字符函数与字符串函数完全指南 目录 1. 字符分类函数 练习将字符串中的小写字母转大写 2. 字符转换函数 3. strlen 的使用和模拟实现⚠️ 易错点示例️ strlen的模拟实现 4. strcpy 的使用和模拟实现️ strcpy的模拟实现 5. strcat 的使用和模拟实现️ 模拟实现strcat函数⚖️ 6. strcmp 的使用和模拟实现️ strcmp函数的模拟实现✂️ 7. strncpy 函数的使用➕ 8. strncat 函数的使用 9. strncmp 函数的使用 10. strstr 的使用和模拟实现️ strstr的模拟实现 11. strtok 函数的使用⚠️ 12. strerror 函数的使用 举例使用strerror处理文件打开错误 了解perror函数 小总结❓ 经典面试题 1. 字符分类函数在编程的过程中我们经常要处理字符和字符串为了方便操作字符和字符串C语言标准库中提供了一系列库函数接下来我们就学习一下这些函数。C语言中有一系列的函数是专门做字符分类的也就是一个字符是属于什么类型的字符的。这些函数的使用都需要包含一个头文件是ctype.h。这些函数的使用方法非常类似我们就讲解一个函数的事情其他的非常类似intislower(intc);islower是能够判断参数部分的c是否是小写字母的。通过返回值来说明是否是小写字母如果是小写字母就返回非0的整数如果不是小写字母则返回0。 练习将字符串中的小写字母转大写写一个代码将字符串中的小写字母转大写其他字符不变。#includestdio.h#includectype.hintmain(){inti0;charstr[]Test String.\n;charc;while(str[i]){cstr[i];if(islower(c))c-32;putchar(c);i;}return0;} 2. 字符转换函数C语言提供了2个字符转换函数inttolower(intc);//将参数传进去的大写字母转小写inttoupper(intc);//将参数传进去的小写字母转大写上面的代码我们将小写转大写是-32完成的效果有了转换函数就可以直接使用toupper函数。#includestdio.h#includectype.hintmain(){inti0;charstr[]Test String.\n;charc;while(str[i]){cstr[i];if(islower(c))ctoupper(c);putchar(c);i;}return0;} 3. strlen 的使用和模拟实现size_tstrlen(constchar*str);字符串以\0作为结束标志strlen函数返回的是在字符串中\0前面出现的字符个数不包含\0。参数指向的字符串必须要以\0结束。注意函数的返回值为size_t是无符号的易错。strlen的使用需要包含头文件string.h。学会strlen函数的模拟实现。⚠️ 易错点示例#includestdio.h#includestring.hintmain(){constchar*str1abcdef;constchar*str2bbb;if(strlen(str2)-strlen(str1)0){printf(str2str1\n);}else{printf(srt1str2\n);}return0;}注意由于strlen返回size_t是无符号类型strlen(str2)-strlen(str1)的结果也是无符号数永远不会小于0。所以即使strlen(str2) strlen(str1)相减结果也会被解释为很大的正数导致判断错误。建议直接比较strlen(str2) strlen(str1)。️ strlen的模拟实现方式1计数器方式intmy_strlen(constchar*str){intcount0;assert(str);while(*str){count;str;}returncount;}方式2递归方式不创建临时变量intmy_strlen(constchar*str){assert(str);if(*str\0)return0;elsereturn1my_strlen(str1);}方式3指针-指针方式intmy_strlen(char*s){assert(str);char*ps;while(*p!\0)p;returnp-s;} 4. strcpy 的使用和模拟实现char*strcpy(char*destination,constchar*source);Copies the C string pointed by source into the array pointed by destination, including the terminating null character (and stopping at that point).源字符串必须以\0结束。会将源字符串中的\0拷贝到目标空间。目标空间必须足够大以确保能存放源字符串。目标空间必须可修改。学会模拟实现。️ strcpy的模拟实现//1.参数顺序//2.函数的功能停止条件//3.assert//4.const修饰指针//5.函数返回值//6.题目出自《高质量C/C编程》书籍最后的试题部分char*my_strcpy(char*dest,constchar*src){char*retdest;assert(dest!NULL);assert(src!NULL);while((*dest*src)){;}returnret;} 5. strcat 的使用和模拟实现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.源字符串必须以\0结束。目标字符串中也得有\0否则没办法知道追加从哪里开始。目标空间必须有足够的大能容纳下源字符串的内容。目标空间必须可修改。字符串自己给自己追加如何️ 模拟实现strcat函数char*my_strcat(char*dest,constchar*src){char*retdest;assert(dest!NULL);assert(src!NULL);while(*dest){dest;}while((*dest*src)){;}returnret;}⚖️ 6. strcmp 的使用和模拟实现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的数字那么如何判断两个字符串比较两个字符串中对应位置上字符ASCII码值的大小。️ strcmp函数的模拟实现intmy_strcmp(constchar*str1,constchar*str2){intret0;assert(str1!NULL);assert(str2!NULL);while(*str1*str2){if(*str1\0)return0;str1;str2;}return*str1-*str2;}✂️ 7. strncpy 函数的使用char*strncpy(char*destination,constchar*source,size_tnum);Copies the first num characters of source to destination. If the end of the source C string (which is signaled by a null-character) is found before num characters have been copied, destination is padded with zeros until a total of num characters have been written to it.拷贝num个字符从源字符串到目标空间。如果源字符串的长度小于num则拷贝完源字符串之后在目标的后边追加0直到num个。➕ 8. strncat 函数的使用char*strncat(char*destination,constchar*source,size_tnum);Appends the first num characters of source to destination, plus a terminating null-character.将source指向字符串的前num个字符追加到destination指向的字符串末尾再追加一个\0字符。If the length of the C string in source is less than num, only the content up to the terminating null-character is copied.如果source指向的字符串的长度小于num的时候只会将字符串中到\0的内容追加到destination指向的字符串末尾。/* strncat example */#includestdio.h#includestring.hintmain(){charstr1[20];charstr2[20];strcpy(str1,To be );strcpy(str2,or not to be);strncat(str1,str2,6);printf(%s\n,str1);return0;} 9. strncmp 函数的使用intstrncmp(constchar*str1,constchar*str2,size_tnum);比较str1和str2的前num个字符如果相等就继续往后比较最多比较num个字母如果提前发现不一样就提前结束大的字符所在的字符串大于另外一个。如果num个字符都相等就是相等返回0。 10. strstr 的使用和模拟实现char*strstr(constchar*str1,constchar*str2);Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1.函数返回字符串str2在字符串str1中第一次出现的位置。The matching process does not include the terminating null-characters, but it stops there.字符串的比较匹配不包含\0字符以\0作为结束标志。/* strstr example */#includestdio.h#includestring.hintmain(){charstr[]This is a simple string;char*pch;pchstrstr(str,simple);strncpy(pch,sample,6);printf(%s\n,str);return0;}️ strstr的模拟实现char*strstr(constchar*str1,constchar*str2){char*cp(char*)str1;char*s1,*s2;if(!*str2)return((char*)str1);while(*cp){s1cp;s2(char*)str2;while(*s1*s2!(*s1-*s2))s1,s2;if(!*s2)return(cp);cp;}return(NULL);} 11. strtok 函数的使用char*strtok(char*str,constchar*sep);sep参数指向一个字符串定义了用作分隔符的字符集合。第一个参数指定一个字符串它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。strtok函数找到str中的下一个标记并将其用\0结尾返回一个指向这个标记的指针。注strtok函数会改变被操作的字符串所以被strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。strtok函数的第一个参数不为NULL函数将找到str中第一个标记strtok函数将保存它在字符串中的位置。strtok函数的第一个参数为NULL函数将在同一个字符串中被保存的位置开始查找下一个标记。如果字符串中不存在更多的标记则返回NULL指针。#includestdio.h#includestring.hintmain(){chararr[]192.168.6.111;char*sep.;char*strNULL;for(strstrtok(arr,sep);str!NULL;strstrtok(NULL,sep)){printf(%s\n,str);}return0;}⚠️ 12. strerror 函数的使用char*strerror(interrnum);strerror函数可以把参数部分错误码对应的错误信息的字符串地址返回来。在不同的系统和C语言标准库的实现中都规定了一些错误码一般是放在errno.h这个头文件中说明的C语言程序启动的时候就会使用一个全局的变量errno来记录程序的当前错误码只不过程序启动的时候errno是0表示没有错误当我们在使用标准库中的函数的时候发生了某种错误就会将对应的错误码存放在errno中而一个错误码的数字是整数很难理解是什么意思所以每一个错误码都是有对应的错误信息的。strerror函数就可以将错误对应的错误信息字符串的地址返回。#includeerrno.h#includestring.h#includestdio.h//我们打印一下0~10这些错误码对应的信息intmain(){inti0;for(i0;i10;i){printf(%s\n,strerror(i));}return0;}在Windows11VS2022环境下输出的结果如下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 举例使用strerror处理文件打开错误#includestdio.h#includestring.h#includeerrno.hintmain(){FILE*pFile;pFilefopen(unexist.ent,r);if(pFileNULL)printf(Error opening file unexist.ent: %s\n,strerror(errno));return0;}输出Error opening file unexist.ent: No such file or directory 了解perror函数也可以了解一下perror函数perror函数相当于一次将上述代码中的第9行完成了直接将错误信息打印出来。perror函数打印完参数部分的字符串后再打印一个冒号和一个空格再打印错误信息。#includestdio.h#includestring.h#includeerrno.hintmain(){FILE*pFile;pFilefopen(unexist.ent,r);if(pFileNULL)perror(Error opening file unexist.ent);return0;}输出Error opening file unexist.ent: No such file or directory 小总结本文详细介绍了C语言中12个常用的字符函数和字符串函数包括函数分类函数名功能 字符分类islower等判断字符类型 字符转换toupper/tolower大小写转换 字符串长度strlen计算字符串长度 字符串拷贝strcpy/strncpy复制字符串 字符串拼接strcat/strncat拼接字符串⚖️ 字符串比较strcmp/strncmp比较字符串 字符串查找strstr查找子串 字符串分割strtok分割字符串⚠️ 错误处理strerror/perror错误信息输出面试重点提醒strlen返回size_t无符号类型直接相减容易出错strcpy/strcat/strcmp的模拟实现是面试高频考点strtok会修改原字符串使用时注意传临时拷贝strncpy/strncat/strncmp是安全版本限制操作长度❓ 经典面试题面试题1strlen与sizeof的区别是什么解答strlen是库函数用于计算字符串长度不包含\0需要包含string.h运行时计算。sizeof是运算符用于计算变量或类型所占内存空间大小包含\0编译时计算。charstr[]hello;printf(%zu\n,strlen(str));// 输出 5printf(%zu\n,sizeof(str));// 输出 6包含\0面试题2为什么strlen(str2)-strlen(str1)0的判断可能出错解答因为strlen返回size_t是无符号整型两个无符号数相减结果仍为无符号数。当strlen(str2) strlen(str1)时相减结果本应为负数但被解释为很大的无符号正数导致判断错误。正确做法是直接比较strlen(str2) strlen(str1)。面试题3strcat能否自己给自己追加为什么解答不能。因为strcat在追加时会覆盖目标字符串的\0然后逐字符拷贝源字符串。如果源和目标指向同一块内存追加过程中源字符串的内容会被覆盖破坏导致无法正确完成追加操作最终结果不可预测。面试题4strcpy和memcpy有什么区别解答strcpy只能用于字符串拷贝遇到\0停止不指定拷贝长度。memcpy可以拷贝任意类型的内存数据按字节数拷贝不依赖\0。strcpy会拷贝\0memcpy不会自动添加\0。面试题5strtok函数为什么一般要传临时拷贝解答因为strtok函数在找到分隔符时会将分隔符位置替换为\0从而修改原字符串。如果直接操作原始字符串会破坏原始数据。因此通常先使用strcpy拷贝一份临时字符串再对临时字符串进行分割操作。