第16讲:字符函数和字符串函数

发布时间:2026/10/10 4:07:32
第16讲:字符函数和字符串函数
目录字符分类函数字符转换函数strlen 的使用和模拟实现strcpy 的使用和模拟实现strcat 的使用和模拟实现strcmp 的使用和模拟实现strncpy 函数的使用strncat 函数的使用strncmp 函数的使用strstr 的使用和模拟实现strtok 函数的使用strerror 函数的使用正文在编程的过程中我们经常要处理字符和字符串。为了方便操作字符和字符串C 语言标准库中提供了一系列库函数接下来我们就学习一下这些函数。1. 字符分类函数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(str1str2\n);}return0;}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*str){assert(str);char*pstr;while(*p!\0)p;returnp-str;}4. strcpy 的使用和模拟实现char*strcpy(char*destination,constchar*source);Copies the C string pointed bysourceinto the array pointed bydestination, 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 firstnumcharacters ofsourcetodestination. If the end of the source C string (which is signaled by a null-character) is found beforenumcharacters have been copied,destinationis padded with zeros until a total ofnumcharacters have been written to it.拷贝num个字符从源字符串到目标空间。如果源字符串的长度小于num则拷贝完源字符串之后在目标的后边追加0直到num个。8. strncat 函数的使用char*strncat(char*destination,constchar*source,size_tnum);Appends the firstnumcharacters ofsourcetodestination, plus a terminating null-character.将source指向字符串的前num个字符追加到destination指向的字符串末尾再追加一个\0字符。If the length of the C string insourceis less thannum, 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 ofstr2instr1, or a null pointer ifstr2is not part ofstr1.函数返回字符串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)returncp;cp;}returnNULL;}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;}在 Windows 11 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举例#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函数相当于一次将上述代码中的第 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