C语言:全面总结字符与字符串函数
【C语言学习笔记】第17讲全面总结字符与字符串函数在敲C代码的过程中尤其是在跟指针和底层内存死磕的时候处理字符和字符串常常让人头疼。为了方便操作C语言标准库中提供了一系列极其强大的库函数。今天我把刚学完的第17讲内容做了系统梳理不仅有核心知识点还总结了超实用的参数记忆心法和实战代码。写成这篇博客既是为了巩固知识也希望能帮到一起学习C/C的同学们 课前必看独家参数记忆心法在实际写代码时很多人经常把函数的参数填反。掌握下面这4个“潜规则”你甚至不需要死记硬背就能猜出参数该怎么填赋值法则左目标右源头想想C语言是怎么赋值的一定是a b;把右边的赋给左边。字符串操作函数完美继承了这个逻辑被修改的永远放在第一个参数Destination。提供数据的永远放在第二个参数Source。寻找const保护伞如果你忘了谁是目标谁是源找const关键字const char *代表这个指针指向的内容是只读的也就是作为提供数据的“源头”。字母 “n” 代表 Number数量只要函数名中间带个n如strncpy,strncat它的最后一个参数一定是一个数字size_t n用来指定操作的最大字符数防止内存越界。英语语序记strstrstrstr(str1, str2)怎么记用英语思维“Find str2 in str1”。大的母字符串在前面要找的小子字符串在后面。一、 字符分类与转换函数ctype.h1. 字符分类函数C语言中有一系列的函数是专门做字符分类的也就是判断一个字符是属于什么类型的字符。这些函数的使用都需要包含头文件ctype.h。判断为真返回非0整数为假返回0。iscntrl判断是否为任何控制字符。isspace判断是否为空白字符如空格、换页\f、换行\n、回车\r、制表符\t等。isdigit判断是否为十进制数字0~9字符。islower/isupper判断是否为小写 / 大写字母。isalpha判断是否为字母a~z或A~Z。2. 字符转换函数tolower(int c)将参数传进去的大写字母转小写。toupper(int c)将参数传进去的小写字母转大写。二、 字符串长度计算strlen功能统计参数指向的字符串中\0之前的字符的个数。头文件string.h⚠️ 避坑指南参数指向的字符串必须要以\0结束。函数的返回值类型为size_t是无符号的易错比较两个strlen的相减结果时千万当心它永远不会是负数。三、 字符串拷贝与追加不受限 vs 受限1. 字符串拷贝strcpy与strncpystrcpy拷贝到源头字符串中的\0为止。会将源字符串中的\0拷贝到目标空间。目标空间必须足够大且可修改。极易因为目标空间不够导致越界strncpy指定了拷贝的长度最多拷贝num个字符相对更加安全。实战代码#includestdio.h#includestring.hintmain(){chardest1[20];chardest2[20]{0};// 养成好习惯初始化数组constchar*srcHello World;// 1. 全部拷贝 (strcpy)strcpy(dest1,src);printf(strcpy: %s\n,dest1);// 输出: Hello World// 2. 受限拷贝 (strncpy)strncpy(dest2,src,5);printf(strncpy: %s\n,dest2);// 输出: Hello (注意只拷贝了5个字符没有World)return0;}2. 字符串追加strcat与strncat功能把源头字符串中的所有字符都追加到目标空间中。⚠️ 避坑指南目标字符串中也得有\0否则没办法知道追加从哪里开始。strncat最多追加num个字符源字符串中不一定要有\0更加灵活安全。实战代码#includestdio.h#includestring.hintmain(){// 注意目标空间必须有足够的大能容纳下源字符串的内容chardest[30]Hello ;constchar*srcWorld!;strcat(dest,src);printf(追加后: %s\n,dest);// 输出: Hello World!return0;}3. 字符串比较strcmp与strncmp功能从两个字符串的第一个字符开始比较如果两个字符的ASCII码值相等就比较下一个字符。返回值第一个字符串大于第二个字符串则返回大于0的数字等于则返回0小于则返回小于0的数字。strncmp最多比较num个字符可以比较任意长度了。四、 字符串查找与分割1. 查找子串strstr功能查找str2指向的字符串在str1指向的字符串中第一次出现的位置。返回值如果存在那么返回第一次出现位置的指针如果不存在那么返回NULL。实战代码#includestdio.h#includestring.hintmain(){charstr[]This is a simple string;char*pch;// 目标在 str 中找到 simple (Find simple in str)pchstrstr(str,simple);if(pch!NULL){printf(找到了后面的内容是: %s\n,pch);// 输出: simple string}return0;}2. 字符串分割strtok功能根据delim参数中指定的分隔符将输入字符串str拆分成多个子字符串。⚠️ 避坑指南破坏性操作strtok会直接修改原始字符串将其中的分隔符替换为\0。如果需要保留原字符串应先拷贝一份后续调用传NULL首次调用时传入待分割的字符串后续调用传入NULL表示继续分割同一个字符串。实战代码#includestdio.h#includestring.hintmain(){charip[]192.168.1.100;// 不能用常量指针因为内容会被修改constchar*sep.;// 第一次调用传入待分割字符串和分隔符char*tokenstrtok(ip,sep);// 循环获取后面的所有部分while(token!NULL){printf(提取到: %s\n,token);// 后续调用传入 NULL 和相同的分隔符继续分割tokenstrtok(NULL,sep);}return0;}五、 错误信息报告errno.h当我们在使用标准库中的函数的时候发生了某种错误就会将对应的错误码存放在errno中。strerror(int errnum)可以通过参数部分的errnum表示错误码得到对应的错误信息并且返回这个错误信息字符串首字符的地址。perror(const char *str)直接将错误信息打印出来。perror函数打印完参数部分的字符串后再打印一个冒号和一个空格再打印错误信息。学习感悟这节课涉及的函数非常多核心在于理解不受限制与受限制函数的区别牢记参数传入的“左目标右源头”原则并在脑海中时刻关注字符串末尾的那个\0。很多玄学Bug往往就出在这里大家一起加油