[C语言]字符函数和字符串函数使用简介
字符函数字符函数都在头文件ctype.h里所包含的函数如下ctype.h字符判断函数其中的isalnum、isalpha、isblank等函数分别可以判断字符的类型他们的用法一样这里简单介绍一下isalnum函数检查一个字符是字母或数字intisalnum(intc);其中的传入函数的形参int c是我们要判断的字符。isalnum函数作用的是判断一个字符是否是字母或者数字如果传入的字符确实是字符或者数字则会返回一个不为0的数true真否则会返回0false假。下面用代码来演示一下其用法示例代码#includecstdio#includecctypevoidcheck(intch){if(isalnum(ch))printf(%c是字母或数字\n,ch);elseprintf(%c不是字母或数字\n,ch);}intmain(){charch1a;charch21;charch3!;check(ch1);check(ch2);check(ch3);return0;}运行结果a是字母或数字 1是字母或数字 !不是字母或数字字符转换函数将大写字母转化为小写字母相当于将当前大写字母加上32inttolower(intc);将小写字母转化为大写字母相当于将当前小写字母减去32inttoupper(intc);示例代码#includestdio.h#includectype.hintmain(){charchA;printf(%c\n,tolower(ch));chb;printf(%c\n,toupper(ch));return0;}运行结果a B可以看到字符转化函数将我们输入的A、b分别转化为了a、B。以上就是我们C语言中处理字符的函数那么我们下面来看看处理字符串的函数吧字符串函数字符串函数都包含在头文件string.h里所以我们使用的时候要包括这个头文件所包含的函数如下string.h。字符串函数的名字有相同的前缀str即 string字符串的缩写。strlen求一个字符串的长度的函数strlen的len是length长度 的缩写顾名思义这个函数就是用来求取字符串函数的长度用的。函数原型size_tstrlen(constchar*str);Get string length Returns the length of the C string _str_.我们可以看到函数传入的参数是一个字符指针返回的是一个size_t类型的无符号的整数。使用的时候我们只需要将字符串的首元素的地址传入函数中就可以获得字符串的长度了。示例代码#includestdio.h#includecstringintmain(){charstr[]Maxine Caulfield;size_t lenstrlen(str);printf(%s len is %zd\n,str,len);return0;}运行结果Maxine Caulfield len is 16其原理是从开头遍历整个字符串直到找到字符串末尾的\0结束这样就把我们的字符串长度求出来了我们也可以自己写一个函数来模拟strlen函数的功能需要注意对传入的形参的合法性进行检验以及出错的处理。strcpy将一个字符串拷贝到另外一个字符串char*strcpy(char*destination,constchar*source);函数介绍功能简介复制字符串将源指针指向的 C 字符串复制到目标指针指向的数组中包括终止空字符并在该位置停止。为避免溢出目标指针指向的数组大小应足够长以容纳与源相同的 C 字符串包括终止空字符并且在内存中不应与源重叠。参数参数说明destination指向目标数组的指针内容将被复制到此处source要复制的 C 字符串返回值返回destination目标字符串的指针。代码示例我们可以看到使用这个函数我们需要传入两个字符指针第一个指针char * destination是目的地的意思需要我们传入要复制到的字符串的首元素的指针第二个指针char * source是源头的意思需要传入我们复制内容的字符串的首元素的指针。然后函数的返回值是返回我们第一个指针的首元素地址这样可以方便我们打印出来下面我们来看看函数的具体使用。代码示例#define_CRT_SECURE_NO_WARNINGS1#includestdio.h#includecstringintmain(){charstr1[]{iiiiiiiiiiiiiiiiiiiiiiiiiii};charstr2[]{I am a student.};printf(%s\n,strcpy(str1,str2));printf(%s\n,str1);// 遍历str1中的字符逐个打印(对 \0 进行特殊处理)for(inti0;isizeof(str1)/sizeof(str1[0]);i){if(str1[i]\0){printf(\\0);// 遇到 \0 输出一个 \0continue;}printf(%c,str1[i]);}return0;}运行结果I am a student. I am a student. I am a student.\0iiiiiiiiiii\0我们调用函数后返回的是字符串指针和str1的指向内容一致。其复制的原理就是将要复制的内容从起始位置往后覆盖字符复制完后会自动在结尾后加上\0作为字符串结束标志位。拷贝结束后str1的内容并不只是有I am a student.\0而是I am a student.\0iiiiiiiiiii\0。我们可以将strcpy里的str1改为了str15改变其拷贝到的目标的起始位置。修改代码printf(%s\n,strcpy(str15,str2));运行结果I am a student. iiiiiI am a student. iiiiiI am a student.\0iiiiii\0注意事项我们使用strcpy的时候要确保目标字符串有足够的空间来存储复制的内容不然就会出现越界访问内存的情况。strncpy限制拷贝的具体个数函数介绍char*strncpy(char*destination,constchar*source,size_t num);功能简介从字符串复制字符将源字符串的前num个字符复制到目标字符串。如果在复制完num个字符之前就遇到了源 C 字符串的结尾以空字符标识则目标字符串会用零填充直到总共写入了num个字符。如果源字符串的长度大于num则不会在目标字符串末尾隐式追加空字符。因此在这种情况下目标字符串不应被视为以空字符结尾的 C 字符串如果这样读取会导致溢出。目标字符串和源字符串不能重叠如果需要处理重叠情况可使用更安全的替代函数memmove。参数参数说明destination指向目标数组的指针内容将被复制到此处source要复制的 C 字符串num要从源字符串复制的最大字符数size_t是一种无符号整数类型返回值返回destination目标字符串的指针。代码示例strncpy所需传入的参数和strcpy要传入的参数和返回值差不多只是多了一个限制复制内容多少的size_t的参数并且不会自动在拷贝结束的时候在结尾后自动添加一个\0空字符。下面我们来看一下strncpy的使用。示例代码#define_CRT_SECURE_NO_WARNINGS1#includestdio.h#includecstring// 打印字符串数组对 \0 进行特殊处理voidprintChArr(constchar*chArr,intn){for(inti0;in;i){if(chArr[i]\0){printf(\\0);// 遇到 \0 输出一个 \0continue;}printf(%c,chArr[i]);}}intmain(){chardes[]{iiiiiiiiiiiiiiiiiiiiiiiiiii};charsrc[]{I am a student.};// src 的长度为 15数组大小为16// 下面分别拷贝 5151618 字符到 des 位置printf(%s\n,strncpy(des,src,5));printf(%s\n,des);printChArr(des,sizeof(des)/sizeof(des[0]));putchar(\n);printf(%s\n,strncpy(des,src,15));printf(%s\n,des);printChArr(des,sizeof(des)/sizeof(des[0]));putchar(\n);printf(%s\n,strncpy(des,src,16));printf(%s\n,des);printChArr(des,sizeof(des)/sizeof(des[0]));putchar(\n);printf(%s\n,strncpy(des,src,18));printf(%s\n,des);printChArr(des,sizeof(des)/sizeof(des[0]));putchar(\n);return0;}运行结果I am iiiiiiiiiiiiiiiiiiiiii I am iiiiiiiiiiiiiiiiiiiiii I am iiiiiiiiiiiiiiiiiiiiii\0 I am a student.iiiiiiiiiiii I am a student.iiiiiiiiiiii I am a student.iiiiiiiiiiii\0 I am a student. I am a student. I am a student.\0iiiiiiiiiii\0 I am a student. I am a student. I am a student.\0\0\0iiiiiiiii\0注意当n 18时除了拷贝了源字符串最后一个位置的\0空字符外还额外补了两个\0可以从最后一行的输出中看到。strcmp比较两个字符串的大小intstrcmp(constchar*str1,constchar*str2);函数介绍功能简介比较两个字符串比较 C 字符串str1和 C 字符串str2。该函数从比较两个字符串的第一个字符开始。如果它们相等则继续比较后续的字符对直到字符不同或遇到终止空字符为止。该函数执行字符的二进制比较。如需考虑区域设置特定规则的函数请参阅strcoll。参数参数说明str1要比较的 C 字符串str2要比较的 C 字符串返回值返回一个整数值指示字符串之间的关系返回值说明 0第一个不匹配的字符在str1中的值小于在str2中的值0两个字符串的内容相等 0第一个不匹配的字符在str1中的值大于在str2中的值代码示例示例代码#includestdio.h#includecstringintmain(){charstr1[]ABCD;charstr2[]ABXX;printf(%d\n,strcmp(str1,str2));return0;}运行结果-1ABCD和ABXX的比较过程如下A 和 A 和进行比较相同往下一个字符进行比较,B 和 B 进行比较也相同也往后进行比较到了C 和 X 开始不一样了C的ASCII码值比X小那么这个时候比较就结束了返回一个小于 0 的数表示字符串ABCD比ABXX小后面的 Z 和 Z 就不进行比较了。strncmp比较两个字符串的大小可以限制比较个数这个函数和strcmp的区别就是多了一个参数来限制比较的范围比如比较上述的ABCZ和ABXX当限制比较范围为2的时候他们会被视为相同也就是返回0。代码示例#includestdio.h#includecstringintmain(){charstr1[]ABCD;charstr2[]ABXX;printf(%d\n,strncmp(str1,str2,2));return0;}运行结果0strcat 和 strncat连接两个字符串char*strcat(char*destination,constchar*source);char*strncat(char*destination,constchar*source,size_t num);strcat的作用是将字符串source在destination末尾处追加。需要注意destination的大小足够容下追加的总内容返回值为destination。strncat和strcat的区别就是strncat可以指定追加的个数示例代码#define_CRT_SECURE_NO_WARNINGS1#includestdio.h#includecstringintmain(){charsrc[]iron man.;chardest[50]I am ;// 预留足够的位置用于追加字符串printf(%s\n,strcat(dest,src));printf(%s\n,strncat(dest,src,4));return0;}运行结果I am iron man. I am iron man.ironstrstr:在字符串里找字符串内容constchar*strstr(constchar*str1,constchar*str2);char*strstr(char*str1,constchar*str2);其功能是传入两个字符串找一下第二个字符串是不是第一个字符串的子集然后返回这个子字符串在第一个字符串中的起始地址如果找不到则返回空指针。示例代码#define_CRT_SECURE_NO_WARNINGS1#includestdio.h#includecstringintmain(){charstr1[]{abcdefgde};char*pFstrstr(str1,de);// 预期返回 str1 3if(pFstr13)printf(pF str1 3\n);printf(%s\n,pFnullptr?not found!:pF);pFstrstr(str1,defz);printf(%s\n,pFnullptr?not found!:pF);// 找不到return0;}运行结果pF str1 3 defgde not found!可以发现当我们在str1中找de时他会返回第一次找到de时的首地址然后我们打印出来确实打印出了defgde当我们要找的内容在str1中找不到时strstr函数就会返回一个空指针。strtok:字符串分割函数char*strtok(char*str,constchar*delimiters);这个函数比较复杂他可以将字符串分割成多个部分并且会将分割点改为\0也就是说他会破坏字符串的内容所以一般我们会使用拷贝的复制品来进行分割操作。函数介绍功能简介将字符串分割为令牌对该函数的一系列调用可以将字符串str分割为令牌这些令牌是由分隔符中的任意字符分隔的连续字符序列。首次调用时该函数期望将 C 字符串作为str参数其第一个字符用作扫描令牌的起始位置。在后续调用中该函数期望传入空指针并使用上一个令牌结束后的下一个位置作为新的扫描起始位置。确定令牌的开始和结束函数首先从起始位置开始扫描找到第一个不在分隔符中的字符即令牌的开始然后从这个令牌开始位置继续扫描找到第一个在分隔符中的字符即令牌的结束如果遇到终止空字符扫描也会停止令牌的结束位置会自动替换为空字符函数返回令牌的开始位置。一旦在strtok调用中找到了str的终止空字符之后所有对该函数的调用第一个参数传空指针都将返回空指针。上次找到令牌的位置由函数内部保存以供下次调用使用特定的库实现不要求避免数据竞争。参数参数说明str要分割的 C 字符串。注意此字符串会被修改分割成更小的子串令牌。也可以传入空指针此时函数会从上一次成功调用结束的位置继续扫描。delimiters包含分隔符字符的 C 字符串。每次调用可以使用不同的分隔符。返回值如果找到令牌返回指向令牌开始位置的指针否则返回空指针当扫描到字符串末尾即遇到空字符时总是返回空指针代码示例代码示例#define_CRT_SECURE_NO_WARNINGS1#includestdio.h#includecstringintmain(){charstr[]{ncbl-2004qq.com/192.168.2.3};constchar*sep/.;for(char*pFstrtok(str,sep);pF!nullptr;pFstrtok(NULL,sep)){printf(%s\n,pF);// 依次输出: ncbl qq com 192 168 2 3}// 输出str数组看一下会将分隔符全部替换为\0for(inti0;isizeof(str)/sizeof(str[0]);i){if(str[i]\0){printf(\\0);continue;}putchar(str[i]);}return0;}运行结果ncbl-2004 qq com 192 168 2 3 ncbl-2004\0qq\0com\0192\0168\02\03\0其中的sep存储了我们分隔符序列这样在进行分割的时候函数会把对应的./替换成\0相当于对字符串进行了分割并且会退出函数后函数会把\0的位置记住即函数会记住\0的地址当我们第一个参数传入空指针的时候函数就会从记住的\0位置往下继续分割当字符串分割到不能再分割的时候就会返回一个空指针。我们可以利用该特性写出对应的for函数来打印其分割的结果。strerror 函数Get pointer to error message stringchar*strerror(interrnum);用来打印错误信息如果程序在运行时发生错误那么就会将其错误信息对应的整数值记录在全局变量errno中我们就可以用strerrorerrno来打印错误信息。我们可以将0-10对应的错误信息打印出来看看。perror是一个更方便打印错误信息的函数我们传入字符串内容作为前缀函数会按照我们的内容拼接错误信息并打印。Print error messagevoidperror(constchar*str);示例代码#define_CRT_SECURE_NO_WARNINGS1#includestdio.h#includecstringintmain(){// 将0-10对应的错误信息打印出来看看。for(inti0;i10;i)printf(%d:%s\n,i,strerror(i));// 方便打印错误的 perror 函数会自动在前缀模板后加:拼接错误描述perror(int main() error);return0;}运行结果0:No error 1:Operation not permitted 2:No such file or directory 3:No such process 4:Interrupted function call 5:Input/output error 6:No such device or address 7:Arg list too long 8:Exec format error 9:Bad file descriptor 10:No child processes int main() error: No error以上就是我对于字符和字符串函数的简介大家最好自己使用这些函数自行体会一下加深印象最好可以模拟实现这些函数。