头文件:#include
看过上一篇的小伙伴们都知道,对于下列函数应该都有所了解.
strcpy函数:.拷贝字符串函数
strcat函数:.追加字符函数
strcmp函数:.字符串拷贝函数
这些函数在使用时,都是遇到’\0’,才停止他们的拷贝,追加,比较等操作
如果我们想要只操作其中的部分,就可以增加一个参数来实现.
由于功能参数等与前面的函数相似,本篇不做重点讲解.
拷贝num个字符从源字符串到目标空间
追加num个源字符到目标空间
比较两个字符串的前num个字符,返回值与strcmp一致.
char * strncpy ( char * destination, const char * source, size_t num );
char * strncat ( char * destination, const char * source, size_t num );
int strncmp ( const char * str1, const char * str2, size_t num );
增加一个size_t 类型的参数num,用于限定原来的函数.
#include#includechar* my_strncpy(char* strDest, const char* strSource, size_t count) { assert(strDest); assert(strSource); char* ret = strDest; while (count--) { *strDest++ = *strSource++; } return ret; } int main() { char arr1[20] = "xxxxxxxxxxxxxx"; char arr2[] = "Hello CSDN!"; int sz2 = sizeof(arr2) / sizeof(arr2[0]); printf("%s", my_strncpy(arr1,arr2,5)); return 0; }
运行结果:
Helloxxxxxxxxx
注意:
1.strncpy只拷贝num个字符,并不会额外附加’\0’字符.
2.如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个.
这个在模拟的时候并没有添加上去.
#include#includechar* my_strncat(char* destination, const char* source, size_t num) { assert(destination); assert(source); char* ret = destination; while (*destination != '\0') { destination++; } while (num--) { *destination++ = *source++; } return ret; } int main() { char arr1[20] = "Hello "; char arr2[] = "CSDN!"; int sz2 = sizeof(arr2) / sizeof(arr2[0]); printf("%s", my_strncat(arr1, arr2, 3)); return 0; }
运行结果:
Hello CSD
#include#includeint my_strncmp(const char* str1, const char* str2, size_t num) { while (num--) { if (*str1 > *str2) { return 1; } else if (*str1 < *str2) { return -1; } str1++; str2++; } return 0; } int main() { char arr1[20] = "aabbccdd"; char arr2[] = "aabbcdef"; int sz2 = sizeof(arr2) / sizeof(arr2[0]); printf("%d", my_strncmp(arr1, arr2, 5)); return 0; }
运行结果:
0
解释:
因为前5个字符相同,num个字符比较结束,认为是相同字符串.
strstr函数
头文件:#include
用于查找主字符串中是否包含子字符串.包含返回第一次匹配成功的字符首地址.不包含则返回NULL.
力扣------找出字符串中第一个匹配的下标.
通过strstr函数找到第一个匹配的字符指针,
该指针-字符串首地址指针=该字符的下标.
int strStr(char * haystack, char * needle){ char*ret=strstr(haystack,needle); if(ret-haystack<0)//小于0时,返回-1; { return -1; } return ret-haystack; }
- 创建三个指针
- p1指向主字符串首地址,p2指向子字符串首地址.
- ret用于保存p1回退的位置.
- 当*p1==p2时,p1和p2继续向后比较,当p1!=*p2时,说明ret位置不对,则ret++
- p1退回到ret位置,p2回到初始位置,重新比较.
- 直到p2指向’\0’,则匹配成功,p1指向’\0’则匹配失败.
代码实现:
#include#includechar* my_strstr(const char* str1, const char* str2) { assert(str1 && str2); if (*str2 == '\0')//如果子字符串是空字符串,直接返回主字符串 { return str1; } const char *ret,*p1,*p2; ret = p1 = str1; p2 = str2; while (*p1&&*p2)//循环停止条件为主字符串或者子字符串有一个为空 { if (*p1 == *p2)//相等则继续比较 { p1++; p2++; } else//不相等则返回指定位置重新比较 { p1 = ++ret; p2 = str2; } } if (*p2 == '\0')//如果子字符串比较结束,则匹配成功 { return ret; } else//否则匹配失败 return NULL; } int main() { char str1[20] = "ABBCDABBACBBD"; char str2[] = "ABBA"; char* ret = my_strstr(str1, str2); if (ret == NULL) { printf("没有找到\n"); } else printf("%s", ret); }
ABBACBBD
strtok函数
头文件:#include
strtok函数
将字符串str根据delimiters 中的字符进行分割.
参数介绍:
参数 | 意义 |
str | 需要被分隔的字符串(第一次传参的时候),传入NULL指针时,会从上一次修改的地址处 |
delimiters | 定义了用作分隔符的字符集合 |
#include#includeint main() { char str1[30] = "123.456.789_111,222@333"; char str2[30]; char a[] = "._,@"; strcpy(str2, str1);//因为strtok函数会改变传过去的字符串的内容,所以我们是将备份传过去 char* ret; //除了第一次调用时第一个参数为str2以外,后面的调用都是传入NULL,这样才会继续向后寻找标记分隔字符. for (ret = strtok(str2, a); ret != NULL; ret = strtok(NULL, a)) { printf("%s\n", ret); } return 0; }
运行结果:
123
456
789
111
222
333
strtok函数并不是一次就将字符串中的所有分隔字符改为’\0’,而是调用它一次,修改一个.
strtok函数第一次调用时,会找到str中的第一个分隔符标记,并将其用 \0 结尾,然后返回一个指向这个标记的指针。
strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。:
strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
如果后面已经没有标记分隔,则返回 NULL 指针.
sterror函数
库函数在使用错误时,会返回一串数字,这些数字就是错误码.
strerror函数用于返回错误码对应的错误信息.
例如:
#include#includeint main() { printf("%s\n", strerror(0)); printf("%s\n", strerror(1)); printf("%s\n", strerror(2)); printf("%s\n", strerror(3)); printf("%s\n", strerror(4)); printf("%s\n", strerror(5)); return 0; }
No error
Operation not permitted
No such file or directory
No such process
Interrupted function call
Input/output error
但是strerror函数并不是这样使用的,因为我们也不知道错误码是什么,像上面这种是属于提前预判了的.
在库函数执行错误后,会将错误码存放在一个error的变量中.所以一般strerror函数是这样使用的.
#include#include#include int main() { //打开文件 FILE* pf = fopen("CSDN.txt", "r"); if (pf == NULL) { //printf("%s\n", strerror(errno)); perror("fopen"); return 1; } //关闭文件 fclose(pf); pf = NULL;//避免空指针 return 0; }
perror函数等价于printf(“%s\n”, strerror(errno));
即strerror函数是返回指向错误信息的字符串地址,而perror函数是将错误信息直接打印出来.
希望这篇文章能帮助大家对c语言中的库函数有关字符函数和字符串函数有更深层的理解.
Copyright © 2023 leiyu.cn. All Rights Reserved. 磊宇云计算 版权所有 许可证编号:B1-20233142/B2-20230630 山东磊宇云计算有限公司 鲁ICP备2020045424号
磊宇云计算致力于以最 “绿色节能” 的方式,让每一位上云的客户成为全球绿色节能和降低碳排放的贡献者