那么接下来我来为大家一一介绍这些库函数是如何使用以及自己如何来模拟实现。
strlen
size_t strlen ( const char * str );
strlen是用来计算字符串中'\0'之前字符的个数的,所以strlen的参数必须以'\0'结束,否则就会出现错误。并且strlen函数的返回值是size_t,说明返回的类型是无符号类型,跟sizeof是一样的,这里我们需要额外注意。知道了strlen的原理之后我们来看看如何自己来模拟实现strlen函数
模拟实现strlen
#include<stdio.h> #include<assert.h> //因为我们这里只是计算字符的个数,不改变字符串里的内容,所以我们用const修饰来增加安全性 int my_strlen(const char* str) { assert(str); //这里同样是增加安全性 char* tmp = (char*)str; int count = 0; while (*tmp != '\0') { count++; tmp++; } return count; } int main() { char str[] = "abcdef"; int ret = my_strlen(str); printf("%d", ret); return 0; }
strcmp
int strcmp ( const char * str1, const char * str2 );
strcmp是根据比较每个字符的ASCII大小来实现的,如果str1的ASCII值大于str2的ASCII值就返回大于0的值,小于就返回小于0的值,相等返回0。看看我们是怎样模拟实现的吧。
模拟实现strcmp
#include<stdio.h> #include<assert.h> int my_strcmp(const char* arr1, const char* arr2) { assert(arr1 && arr2); char* str1 = (char*)arr1; char* str2 = (char*)arr2; //如果*str1==*str2,str1和str2就++,看后面的是否相同 while (*str1 == *str2) { str1++; str2++; } //跳出循环的情况有两种:第一种是字符串都走到'\0'的位置了,这就说明两个字符串相等 // 第二种就是两个字符串中对应的两个字符不相等, //所以这里我们就需要做出判断 if (*str1 == '\0') return 0; else return *str1 - *str2; } int main() { char arr1[] = "abcd"; char arr2[] = "abed"; int ret = my_strcmp(arr1, arr2); printf("%d", ret); return 0; }
strcpy
char* strcpy(char * destination, const char * source );
这个函数的意思是将source中的函数拷贝到destination中,这里我们需要注意的是,拷贝的时候是从destination的'\0'开始的,将destination的'\0'给覆盖了,所以source中必须得有'\0',不仅如此,source中的内容也需要'\0'结束,并且destination的空间必须足够大,不然会出现错误,更重要的是destination空间必须是可变的。
模拟实现strcpy
#include<stdio.h> #include<assert.h> void my_strcpy(char* arr1, const char* arr2) { assert(arr1 && arr2); char* str1 = arr1; char* str2 = (char*)arr2; while (*str1++ = *str2++) { ; } } int main() { char arr1[] = "abcd"; char arr2[] = "bcde"; my_strcpy(arr1, arr2); printf("%s", arr1); return 0; }
strcat
char * strcat ( char * destination, const char * source );
这个函数的作用是将source中的内容追加到destination的后面,这也是从destination的'\0'开始的。
模拟实现strcat
#include<stdio.h> #include<assert.h> void my_strcat(char* arr1, const char* arr2) { assert(arr1 && arr2); char* str1 = arr1; char* str2 = (char*)arr2; while (*str1 != '\0') /找到destination的'\0'位置 { str1++; } while (*str1++ = *str2++) { ; } } int main() { char arr1[12] = "hello "; char arr2[] = "world"; my_strcat(arr1, arr2); printf("%s", arr1); return 0; }
strncmp
int strncmp ( const char * str1, const char * str2, size_t num );
这个函数可以指定比较的字符个数,相对于strcmp来说就安全一点。我们来看看这个函数是如何实现的吧/
模拟实现strncmp
#include<stdio.h> #include<assert.h> int my_strncmp(const char* arr1, const char* arr2,int n) { assert(arr1 && arr2); char* str1 = (char*)arr1; char* str2 = (char*)arr2; for(int i = 0; i<n; i++) { if(*str1 != *str2) return *str1-*str2; } return 0; } int main() { char arr1[] = "abcd"; char arr2[] = "abed"; int ret = my_strncmp(arr1, arr2,2); printf("%d", ret); return 0; }
strncpy
char * strncpy ( char * destination, const char * source, size_t num );
指定将source中的几个字符拷贝到destination中。结果返回destination的首地址。
模拟实现strncpy
#include<stdio.h> #include<assert.h> char* my_strncpy(char* arr1, const char* arr2,int n) { assert(arr1 && arr2); char* str1 = arr1; char* str2 = (char*)arr2; for(int i = 0; i<n; i++) { *str1++ = *str2++; } return arr1; } int main() { char arr1[] = "abcd"; char arr2[] = "bcde"; printf("%s", my_strncpy(arr1, arr2,3)); return 0; }
这里再拷贝了之后会不会在destination后面自动填写一个'\0'呢?我们通过一个代码来看看。
这里我们可以看到,strncpy是不会自动补'\0'的。如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到n个。
strncat
char * strncat ( char * destination, const char * source, size_t num );
指定source中的n个字符追加到destination中。
模拟实现strncat
#include<stdio.h> #include<assert.h> char* my_strncat(char* arr1, const char* arr2,int n) { assert(arr1 && arr2); char* str1 = arr1; char* str2 = (char*)arr2; while (*str1 != '\0') { str1++; } for(int i = 0; i<n; i++) { *str1++ = *str2++; } return arr1; } int main() { char arr1[12] = "hello "; char arr2[] = "world"; printf("%s", my_strncat(arr1, arr2,3)); return 0; }
那么这里会不会自动补'\0'呢?我们来看看。
答案是会的,再拷贝完你指定的字符个数后,会在后面自动补上一个'\0'。
strstr
char * strstr ( const char *str1, const char * str2);
在字符串str1中查找是否有str2字符串。如果有就返回str1中第一个str2字符串的地址。
模拟实现strstr
#include<stdio.h> #include<assert.h> char* findStr(const char* arr1,const char* arr2) { assert(arr1 && arr2); //用s1来记录跟str2首字符相等的位置,以便cur1在找到首字符相等时,继续找后面字符是否相等,但不 //相等的时候,将cur1返回到第一个字符相等的位置,在进行后面的查找。 char* s1 = NULL; //s2跟s1的作用是类似的 char* s2 = (char*)arr2; char* cur1 = (char*)arr1; while (*cur1 != '\0') { char* cur2 = s2; while (*cur1 != *cur2) { cur1++; } s1 = cur1; while (*cur2 != '\0') { if (*cur1 != *cur2) break; cur1++; cur2++; } if (*cur2 == '\0') return s1; cur1 = s1; cur1++; } return NULL; } int main() { char arr1[] = "abcdef"; char arr2[] = "bcd"; printf("%s", findStr(arr1,arr2)); return 0; }
如何在arr1中找到arr2最后出现的地址
#include<stdio.h> #include<assert.h> char* findStr(const char* arr1,const char* arr2) { assert(arr1 && arr2); char* s1 = NULL; char* s2 = (char*)arr2; char* cur1 = (char*)arr1; //ret来记录每个出现arr2完整字符串的首元素地址 char* ret = NULL; while (*cur1 != '\0') { char* cur2 = s2; while (*cur1 != *cur2) { cur1++; } s1 = cur1; while (*cur2 != '\0') { if (*cur1 != *cur2) break; cur1++; cur2++; } if (*cur2 == '\0') { ret = s1; } cur1 = s1; cur1++; } return ret; }
那么这些就是我所要分享的我学到的所有关于字符串函数的内容了,谢谢大家的观看,希望对大家能有帮助。