长度受限制的字符串函数
strncpy函数:
第三个参数 size_t count 是要拷贝的元素个数
要注意的是当我们拷贝的元素个数大于我们被拷贝的字符串的长度时他会自动往不够的那片空间添加'\0'
#include <stdio.h> int main() { char string1[]="xxxxxxxxxxx"; char string2[]="123"; strncpy(string1,string2,5); 这时string1就会变成123'\0'\0'xxxxxxxxx; }
同时strncpy函数也更加安全一些 因为这样可以避免你拷进去的字符串过长 以至于目标的字符串不足以存储拷贝进来的字符串
#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <assert.h> char* my_strncpy(char* rest, const char* tmp, unsigned int num) { assert(rest && tmp); char* ret = rest; while (num) { if (*tmp == '\0') { *rest++ = *tmp; num--; } while (*tmp) { *rest++ = *tmp++; num--; if (!num) return ret; } } return ret; } int main() { char rest[] = "xxxxxxxxxx"; char tmp[] = "123"; printf("%s",my_strncpy(rest, tmp, 5));//这里打印出来也就是123 前面已经给大家说过了 }
这个是库函数里的写法
char * __cdecl strncpy ( char * dest, const char * source, size_t count ) { char *start = dest; while (count && (*dest++ = *source++) != '\0') /* copy string */ count--; if (count) /* pad out with zeroes */ while (--count) *dest++ = '\0'; return(start); }
strncat函数:
这个是往目标字符串追加 size_t num 的字符个数的字符串
要注意的点除了前面说的 追加字符串要足够长 可变以外
这个函数还有一个要注意的点 在指定链接的字符个数后 如果我们原函数的长度大于字符串的长度 就好像这样 "hello" "world"这时如果链接的字符个数 num为3 那我们链接wor后
后面应该是什么样呢
#include <stdio.h> int main() { char string1[]="hello"; char string2[]="world"; strncpy(string1,string2,3); 这样操作后string1的结果是什么内 留给大家思考一下 }
提示 我们既然时链接两个字符串 那我们链接后肯定也是一个字符串 即使链接的元素个数中没有'\0' 大家想想字符串不可少的是什么 就知道答案了
#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <assert.h> char* my_strncat(char* rest,const char* tmp,unsigned int num) { assert(rest && tmp); char* ret = rest; while (*rest) { rest++; } while (*tmp) { *rest++ = *tmp++; num--; if (!num)break; } *rest = '\0'; return ret; } int main() { char string1[20] = "hello"; char string2[] = "world"; printf("%s",my_strncat(string1, string2, 4)); }
这个是库函数里的写法
char * __cdecl strncat ( char * front, const char * back, size_t count ) { char *start = front; while (*front++) ; front--; while (count--) if ((*front++ = *back++) == 0) return(start); *front = '\0'; return(start); }
strncmp函数:
还是一样的道理 这个也是指定了比较的元素的个数
#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <assert.h> int my_strncmp(const char* rest, const char* tmp, unsigned int num) { assert(rest && tmp); while (*rest == *tmp) { num--; if (!num ||(* rest == '\0'))break; rest++; tmp++; } return *rest - *tmp; } int main() { char string1[] = "abczefg"; char string2[] = "abcqqq"; printf("%d",my_strncmp(string1, string2, 4)); }
这个是库函数的里的写法
int __cdecl strncmp ( const char *first, const char *last, size_t count ) { size_t x = 0; if (!count) { return 0; } /* * This explicit guard needed to deal correctly with boundary * cases: strings shorter than 4 bytes and strings longer than * UINT_MAX-4 bytes . */ if( count >= 4 ) { /* unroll by four */ for (; x < count-4; x+=4) { first+=4; last +=4; if (*(first-4) == 0 || *(first-4) != *(last-4)) { return(*(unsigned char *)(first-4) - *(unsigned char *)(last-4)); } if (*(first-3) == 0 || *(first-3) != *(last-3)) { return(*(unsigned char *)(first-3) - *(unsigned char *)(last-3)); } if (*(first-2) == 0 || *(first-2) != *(last-2)) { return(*(unsigned char *)(first-2) - *(unsigned char *)(last-2)); } if (*(first-1) == 0 || *(first-1) != *(last-1)) { return(*(unsigned char *)(first-1) - *(unsigned char *)(last-1)); } } } /* residual loop */ for (; x < count; x++) { if (*first == 0 || *first != *last) { return(*(unsigned char *)first - *(unsigned char *)last); } first+=1; last+=1; } return 0; }
strstr函数:
这是一个在字符串中寻找目标字符串的函数 如果找到则返回被寻找字符串首元素在目标字符串的地址
#include <stdio.h> int main() { char string1[]="abbcqwer"; char string2[]="bbc" printf("%s",strstr(string1,string2)); 打印出来的就是 bbcqwer }
我们来理一下模拟这个函数的思路 首先 我们是要在目标字符串寻找 肯定需要几个指针来帮我们判断是不是我们要寻找的字符串
#include <stdio.h> #include <assert.h> char* my_strstr(const char* tmp, const char* ret) { assert(tmp && ret); const char* suter = tmp;//被寻找字符串的枚举地址 const char* cstr = tmp;//被寻找字符串的起始地址 const char* sup = ret; if (*ret == '\0') { return tmp; } while (*cstr) { suter = cstr; sup = ret; while (*suter&&*suter == *sup)//当是这种"afbbc" "bbc" 最后'\0'和'\0'相同会一直循环随 会跳出但结果就会出问题 { //所以suter和sup指向不能为'\0' suter++; sup++; } //上面那种循环我的if语句sup要放前面 我是找到了的而且两个都 是'\0'要把bbc打印出来才行 if (*sup == '\0') //像是这种"afbbcfgh" "bbc" 这时发现不相等我的sup会指向'\0'就 可以结束了 { return (char*)cstr; } if (*suter == '\0')//"afbbbc" "bbcd"这种就是我往后寻找suter已经到'\0'了就可以结束了 { //虽然没有也行 但是就要等到cstr到'\0'才停止 这样就可以早点结束 return NULL; } cstr++; } return NULL; } int main() { char arr1[] = "afbbbcdfgh"; char arr2[] = "bbc"; printf("%s",my_strstr(arr1, arr2)); }
我们把那个我所说的s1s2的赋值放在循环的前面 只要不相等我们跳出循环就会来到开始的位置 s1s2自然就恢复开始的位置了
strtok函数:
这个函数的第二个参数我们这里简称 s2 是一个字符串 里面存储的是多个分隔符的集合
第一个参数指定一个字符串,它包含了0个或多个由s2字符串中一个或者多个分隔符分割的标记
strtok函数找到s1中的下一个标记 并将其'\0'结尾 返回一个指向该标记的指针
strtok函数的第一个参数不为NULL 函数将找到str的第一个标记 strtok函数将保存他在字符串中的位置
strtok函数的第一个参数为NULL 函数将在同一个字符串中被保存的位置开始查找下一个标记
不存在更多标记则返回NULL
#include <stdio.h> int main() { const char* p="@."; char arr[] = "luck++@8023.sg"; char buf[] = { 0 }; strcpy(arr,buf); //因为我们的这个函数会改变原本字符串的内容 所以要先拷贝一份 char* str=strtok(arr,p);//luck++ printf("%s",str); str=strtok(arr,p);//8023 printf("%s",str); str=strtok(arr,p);//sg printf("%s",str); //strtok 这里返回NULL }
但是这种写法是不可取的 这样才是正确的用法
const char* p="@."; char *arr="luck++@8023.sg"; for(char* str=strtok(arr,p);str!=NULL;str=strtok(NULL,p)) { printf("%s\n",str); }
strerror函数:
这是一个错误信息的解释 报告函数 返回错误信息字符串的首地址
c语言中:
错误码-错误信息
0 -“No error”
其中errno一般与strerror配合着使用
当库函数使用的时候,发生错误会把errno这个全局的错误变量设置为本次执行库函数产生的错误码
errno是c语言提供的一个全局变量,可以直接使用,放在errno.h文件中
字符分类函数:
字符转换函数:
int tolower(int c);将字符转换成小写
int toupper(int c); 将字符转换成大写
到这里字符相关的函数就 弄完了 祝大家都能收到自己心仪的大厂的offer!!!!