字符和字符串的重点内容是能熟练使用字符串相关的函数以及能够模拟实现这些函数。
下面列举一些常用的字符串函数,这些字符串函数大家可以通过网站cplusplus.com - The C++ Resources Network
详细的了解其具体的功能,这也是后面模拟实现这些函数的基础 。
strlen
strlen能够求出字符串所占的字节大小,字符串末尾的 '\0' 不计算在内,接下来我们模拟实现strlen函数,有三种实现方法
//利用计数变量的方法 int my_strlen( char *str ) { int num = 0; if (*str++ != '\0' ) { num++; } return num; } //指针减指针的方法 int my_strlen( char *str ) { char *p = str; while ( *p++ != '\0' ) { ; } return p-str; } //递归的方法 int my_strlen( char *str ) { if ( *str == '\0' ) return 0; else return 1+my_strlen(str+1); }
strcpy
strcpy能够将一串字符串的内容拷贝到另一块字符空间里,其中 '\0' 也会被拷贝过去,其中源字符串必须以 '\0' 结束,目标空间必须足够大,以确保能存放源字符串。
void my_strcpy(char *buff1, const char* buff2) { while (*buff1++ = *buff2++ ) { ; } }
memcpy
当然如果只能拷贝字符类型的内容,那肯定是不能够满足日常需求的,而memcpy能够实现拷贝所有类型的数据,其原理就是一个字节一个字节的拷贝,把每一个字节的二进制数赋值到另一块空间上,最终能够实现数据的拷贝,该函数的返回值是目标空间的初始指针
void* my_memcpy(void* dest, const void* src, int num) { while ( num--) { *((char*)dest)++ = *((char*)src)++; } }
strcat
stract是把一个字符串的内容接到另一个字符串的后面,其中源字符串必须以 '\0' 结束。,目标空间必须足够的大,能容纳下源字符串的内容,不然会越界访问和非法修改
my_strcat(char* dest, const char* src) { while(*dest) { dest++; } while (*dest++ = *src++ ) { ; } }
memmove
memmove可以将一个字符串某个字符后面指定大小的内容覆盖到另一个指定位置上,例如字符串char arr[] = "memmove can be very useful......" ; 从arr+15开始后面的11个字节的内容拷贝到arr+20这个位置上,那么最终的结果就是 "memmove can be very very useful." 想法很简单,但这里有一个坑,如果像 *dest++ = *src++ 这样一个一个覆盖会出问题,当我们走到arr+20的位置时,原来的 usef 已经被替换成very 所以我们要将要覆盖的内容先复制下来,再进行覆盖
void* my_memmove(void* dest, const void* src, int num) { char* p = (char*) malloc(num); char* tmp = p; if (p == NULL) { return; } for(int i =0; i<num; i++) { *p++ = *((char*)src)++; } p = tmp; for (int i = 0; i < num; i++) { *((char*)dest)++ = *p++; } p = tmp; free(p); } int main() { char arr1[] = "memmove can be very useful......"; my_memmove(arr1+20, arr1+15, 11); printf("%s ", arr1); }
有一点要注意的是在释放p的时候要把还原到初始位置,不然空间无法释放掉。
strcmp
strcmp函数用来比较两个字符串,如果两个字符串相等返回0,不相等就返回对应的ASCII值之差
int my_strcmp(const char* p1, const char* p2) { while (*p1 == *p2) { if (*p1 == '\0') return 0; p1++; p2++; } return (*p1 - *p2); }
strstr
strstr函数用来检测一个字符串的子串,给两个字符串,如果其中一个短字符串是长字符串的子串,那么就返回短字符串在长字符串处的指针,不是长字符串的子串就返回空指针
char* my_strsstr(const char* str1, const char* str2) { const char* s1 = str1; const char* s2 = str2; const char* p = str1; while(*p) { s1 = p; s2 = str2; while(*s1 != '\0' && *s2 != '\0' && *s1 == *s2) { s1++; s2++; } if(*s2 == '\0') { return (char*)p; } p++; } return NULL; }
该算法的效率低下,可以看看KMP算法
strerror
strerror是用来返回报错信息的,通过接收errno的报错码,再使用printf函数打印出报错信息
int main() { int* p = (int*)malloc(sizeof(int) * 10000000000000000000); if (p == NULL) { printf("%s", strerror(errno)); return 1; } } //运行结果为: Not enough space
以上就是常见的字符串函数,牢牢掌握能节省很多时间