欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

字符串&内存函数(详解)

时间:2023-06-06

目录

一、长度不受限制的字符串函数

1.strlen函数

​2.strcpy函数

3.strcat函数 

4.strcmp函数 

二、 长度受限制的字符串函数

1.strncpy函数

2.strncat函数 

​3.strncmp函数

三、其他字符串函数

1.strstr函数

2.strtok函数

四、内存操作函数

1.memcpy函数 

2.memmove 函数

3.memcmp函数 

4.memset函数

​五、库函数的模拟实现

1.模拟实现strlen函数

①递归实现

②计数器实现

③指针 - 指针

2.模拟实现strcpy函数

3.模拟实现strcat函数

4.模拟实现strcmp函数

5.模拟实现strncpy函数

6.模拟实现strncat函数

7.模拟实现strncmp函数

8.模拟实现strstr函数

9.模拟实现memcpy函数

10.模拟实现memmove函数

11.模拟实现memcmp函数

12.模拟实现memset函数

六、总结


一、长度不受限制的字符串函数

1.strlen函数

字符串以‘’作为结束标志,strlen函数返回的是字符串前面出现的字符个数

函数原型:size_t strlen( const char *string );

头 文 件 :

函数功能:计算字符串的长度;

注意事项:1.定义的字符串必须要包含''

char arr1[] = "abcd";char arr2[] = { 'a', 'b', 'c', 'd' };

举例:

#include #include int main(){char str1[] = "ABCD";//里面包含char str2[] = { 'A','B','C','D' };//里面不包含printf("%dn", strlen(str1));printf("%dn", strlen(str2));return 0;}

2.strcpy函数

函数原型:char *strcpy( char *strDestination, const char *strSource );

头 文 件 :

函数功能:字符串拷贝;它是连同''一起拷贝过去;

参数解读:

                  1.char *strDestination --- 目标字符串

                  2.const char *strSource  --- 源字符串(不可被修改)

                  3.返回类型:char* --- 返回的是拷贝后源字符串的地址

注意事项:

                1.拷贝时源字符串中一定要包含;

                2.拷贝时目标空间要足够大,保证放的下要拷贝过去的字符串;

                3.拷贝时目标空间必须可修改(不能被const修饰);

 举例:

#include #include int main(){char str1[20] = "xxxxxxx";//目标空间要足够大char str2[] = "Hello World";printf("拷贝前为:%sn", str1);strcpy(str1, str2);printf("拷贝后为:%sn", str1);return 0;}

3.strcat函数 

函数原型:char *strcat( char *strDestination, const char *strSource );

头 文 件 :

函数功能:字符串连接(追加):它是连同''一起追加过去;

参数解读:

                  1.char *strDestination --- 目标字符串

                  2.const char *strSource  --- 源字符串(不可被修改)

                  3.返回类型:char* --- 返回的是拷贝后源字符串的地址

注意事项:

                 1.追加时源字符串中一定要包含

                 2.追加时目标空间要足够大,保证放的下要追加过去的字符串

                 3.追加时目标空间必须可修改(不能被const修饰)

                 4.自己不能给自己追加(需要使用strncat)

举例:

#include #include int main(){char str1[20] = "Hello ";//目标空间要足够大char str2[] = "World";printf("追加前为:%sn", str1);strcat(str1, str2);printf("追加后为:%sn", str1);return 0;}

4.strcmp函数 

函数原型:int strcmp( const char *string1, const char *string2 );

头 文 件 :

函数功能:字符串比较:比较的是ASSIC码值;比较的是内容而不是长度;

参数解读:

                  1.string1 --- 被比较的字符串;

                  2.string2 --- 待比较的字符串;

比较方法:

                  1.当 str1 < str2  返回负数

                  2.当 str1 = str2  返回0

                  3.当 str1 > str2  返回正数 

举例:

#include #include int main(){char str1[] = "ABCD";char str2[] = "ABCE";int ret = strcmp(str1, str2);if (ret > 0){printf("ret=%d:str1>str2n", ret);}else if (ret < 0){printf("ret=%d:str1

 

二、 长度受限制的字符串函数

1.strncpy函数

函数原型:char *strncpy( char *strDest, const char *strSource, size_t count );

头 文 件 :

函数功能:字符串拷贝:可以指定拷贝字符的个数;

参数解读:

                  1.char *strDest --- 目标字符串

                  2.const char *strSource  --- 源字符串(不可被修改)

                  3.size_t count --- 指定拷贝多少个字符

                  4.返回类型:char* --- 返回的是拷贝后源字符串的地址

注意事项:

                  1.拷贝时:当拷贝的个数大于源字符串长度时(比如源字符串“abcd”,拷贝6个),不够的用补(设置个数时要合理)

                  2.拷贝时目标空间要足够大,保证放的下要拷贝过去的字符串

                  3.拷贝时目标空间必须可修改(不能被const修饰)

举例:

#include #include int main(){char dest[20] = "xxxxxxx";char src[] = "Hello World";printf("拷贝前为:%sn", dest);strncpy(dest, src,5);printf("拷贝后为:%sn", dest);return 0;}

#include #include int main(){char dest[20] = "xxxxxxxxxx";char src[] = "abcd";printf("拷贝前为:%sn", dest);strncpy(dest, src, 6);printf("拷贝后为:%sn", dest);return 0;}

 

2.strncat函数 

函数原型:char *strncat( char *strDest, const char *strSource, size_t count );

头 文 件 :

函数功能:字符串追加:可以指定追加字符的个数;

参数解读:

                  1.char *strDest --- 目标字符串

                  2.const char *strSource  --- 源字符串(不可被修改)

                  3.size_t count --- 指定追加多少个字符

                  4.返回类型:char* --- 返回的是拷贝后源字符串的地址

注意事项:

                  1.追加时:当追加的个数小于源字符串的个数时,会主动追加''

                  2.追加时:当追加的个数大于源字符串的个数时,库函数的定义是只追加到''位置,所以个数就算很大并不影响

                  3.追加时目标空间必须可修改(不能被const修饰)

 举例:

#include #include int main(){char dest[20] = "Hello ";char src[] = "World";printf("追加前为:%sn", dest);strncat(dest, src, 4);printf("追加后为:%sn", dest);return 0;}

3.strncmp函数

函数原型:int strncmp( const char *string1, const char *string2, size_t count );

头 文 件 :

函数功能:字符串比较:可以指定比较字符的个数;

参数解读:

                  1.string1 --- 被比较的字符串;

                  2.string2 --- 待比较的字符串;

                  3.size_t count --- 指定 比较多少个字符 (从前向后比较)

比较方法:

                  1.当 str1 < str2  返回负数

                  2.当 str1 = str2  返回0

                  3.当 str1 > str2  返回正数 

举例:

#include #include int main(){char str1[] = "ABCD";char str2[] = "ABCE";int ret = strncmp(str1, str2,3);if (ret > 0){printf("ret=%d:str1>str2n", ret);}else if (ret < 0){printf("ret=%d:str1

 

三、其他字符串函数

1.strstr函数

函数原型:char *strstr( const char *string, const char *strCharSet );

头  文  件:

函数功能:字符串查找:在string中查找strCharSet是否存在;

参数解读:

                  1.string --- 被搜索的以空结尾的字符串;

                  2.strCharSet --- 要搜索的以空结尾的字符串;

注意事项:

                  1.当找到时:返回一个指针 strCharSet string中第一次出现的那个位置;

                  2.未找到时:返回一个空指针(NULL);

举例:

#include #include int main(){char str1[] = "ABCD";char str2[] = "BC";char str3[] = "HaHa";if (strstr(str1, str2) != NULL){printf("找到了n");}else{printf("找不到n");}return 0;}

2.strtok函数

函数原型:char *strtok( char *strToken, const char *strDelimit ); 

头  文  件:

函数功能:字符串切分

功能:

        1.sep参数是个字符串,定义了用作分隔符的字符集合

        2.第一个参数指定一个字符,它包含0个或多个由sep字符串中一个或多个分隔符分割的标记

        3.strtok函数找到str中的下一个标记,并将其用 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)

        4.strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。

        5.strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。

        6.如果字符串中不存在更多的标记,则返回 NULL 指针

 举例:

#include #include int main(){char arr1[] = "zhangsan@school.student";char arr2[100] = { 0 };char sep[] = "@.";strcpy(arr2, arr1);char* ret = NULL;for (ret = strtok(arr2, sep); ret != NULL;ret=strtok(NULL,sep)){printf("%sn", ret);}return 0;}

 

四、内存操作函数

1.memcpy函数 

函数原型:void *memcpy( void *dest, const void *src, size_t count ); 

头  文  件:or

函数功能:内存拷贝:(适用于内存不重叠的场景)

功能:

        1.函数memcpy从src的位置开始向后复制count个字节的数据到dest的内存位置;

        2.这个函数在遇到 的时候并不会停下来;

        3.如果source和destination有任何重叠,复制的结果都是未定义的;

 举例:

#include #include int main(){int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };memcpy(arr1, arr1 + 4, 16);//arr1+2是指向5的,从这个位置向后16个字节的数据存到arr1向后16个字节//也就是把5 6 7 8 拷贝到1 2 3 4 上去for (int i = 0; i < 10; i++){printf("%d ", arr1[i]);}printf("n");return 0;}

2.memmove 函数

函数原型:void *memmove( void *dest, const void *src, size_t count ); 

头  文  件:

函数功能:内存拷贝:(适用于内存重叠或不重叠的场景)

注意事项:

        1.和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
        2.如果源空间和目标空间出现重叠,就得使用memmove函数处理

举例:

#include #include int main(){int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };memmove(arr1, arr1 + 2, 16);//arr1+2是指向3的,从这个位置向后16个字节的数据存到arr1向后16个字节//也就是把3 4 5 6 拷贝到1 2 3 4 上去(这里就是内存重叠了,重叠的位置是3 4)for (int i = 0; i < 10; i++){printf("%d ", arr1[i]);}printf("n");return 0;}

3.memcmp函数 

函数原型:int memcmp( const void *buf1, const void *buf2, size_t count );

头  文  件:or

函数功能:内存比较:(比较buf1buf2指针开始的num个字节)

比较方法:

                1.当buf1<buf2时 返回<0

                2.当buf1=buf2时 返回=0

                3.当buf1>buf2时 返回>0

举例:

#include #include int main(){int arr1[] = { 1,2,3,4,5 };int arr2[] = { 1,2,3,6,6 };int ret = memcmp(arr1, arr2, 12);//这里向后比较12个字节,就是比较1 2 3if (ret > 0){printf("ret=%d arr1>arr2n", ret);}else if (ret < 0){printf("ret=%d arr1

 

4.memset函数

函数原型:void *memset( void *dest, int c, size_t count );

 头  文  件:or

函数功能:内存设置(memset函数将dest的第一个count个字节设置为字符c)

举例:

#include #include int main(){char str[] = "almost every programmer should know memset!";memset(str, '-', 6);//从起始位置开始向后6个字节的内容改为 '-'puts(str);return 0;}

五、库函数的模拟实现

1.模拟实现strlen函数

①递归实现

#include int my_strlen(const char* pa){if (*pa != ''){return 1 + my_strlen(pa + 1);//1+1+1+1+1+1+0}else{return 0;}}int main(){char arr[] = "abcdef";int ret = my_strlen(arr);printf("arr的长度为:%dn", ret);return 0;}

②计数器实现

#include int my_strlen(const char* pa){int count = 0;for (int i = 0; pa[i] != ''; i++){count++;//只要不等于 就加一}return count;}int main(){char arr[] = "abcdef";int ret = my_strlen(arr);printf("arr的长度为:%dn", ret);return 0;}

③指针 - 指针

#include int my_strlen(const char* pa){char* pa1 = pa;//先保存首元素的地址while (*pa1){pa1++;//去找 的地址}return pa1 - pa;//pa1是 的地址,pa是首元素的地址;相减就得到元素个数}int main(){char arr[] = "abcdef";int ret = my_strlen(arr);printf("arr的长度为:%dn", ret);return 0;}

2.模拟实现strcpy函数

#include #include char* my_strcpy(char* dest, const char* src){assert(dest && src);//断言 --- 判断这两个指针是否为空 char* ret = dest;while (*dest++ = *src++)//直接赋值,直到遇到''就停下{;} return ret;}int main(){char arr1[20] = "xxxxxx";char arr2[] = "Hello";printf("拷贝前为:%sn", arr1);char* ret = my_strcpy(arr1, arr2);printf("拷贝后为:%sn", ret);return 0;}

#include #include char* my_strcpy(char* dest, const char* src){assert(dest && src);//断言 --- 判断这两个指针是否为空int i = 0;for (i = 0; src[i] != ''; i++){dest[i] = src[i];//赋值,但是没有''结束标志}dest[i] = '';//末尾添加一个''}int main(){char arr1[20] = "xxxxxx";char arr2[] = "Hello";printf("拷贝前为:%sn", arr1);my_strcpy(arr1, arr2);printf("拷贝后为:%sn", arr1);return 0;}

3.模拟实现strcat函数

#include #include char* my_strcat(char* dest, const char* src){assert(dest && src);//断言 --- 判断这两个指针是否为空while (*dest){//先找到dest所指向的数组中''的位置dest++;}while (*src){*dest++ = *src++;//进行追加}}int main(){char arr1[20] = "Hello ";char arr2[] = "World";printf("追加前为:%sn", arr1);my_strcat(arr1, arr2);printf("追加后为:%sn", arr1);return 0;}

4.模拟实现strcmp函数

#include #include int my_strcmp(char* str1, const char* str2){assert(str1 && str2);//断言 --- 判断这两个指针是否为空while (*str1==*str2){if (*str1 == ''){return 0;}str1++;str2++;}return *str1 - *str2;}int main(){char arr1[] = "ABCDEF";char arr2[] = "ABCDE";int ret = my_strcmp(arr1, arr2);if (ret > 0){printf("ret = %d:arr1>arr2", ret);}else if (ret < 0){printf("ret = %d:arr1

5.模拟实现strncpy函数

#include #include char* my_strncpy(char *dest, const char *src,size_t count){assert(dest && src);char *ret = dest;//1.拷贝字符串的个数while (count && (*dest++ = *src++)){count--;}//2.不够的用补if (count){while (--count){*dest++ = '';}}return ret;}int main(){char arr1[20] = "xxxxxxxx";char arr2[] = "Hello World";printf("拷贝前为:%sn", arr1);char* ret = my_strncpy(arr1, arr2, 5);printf("拷贝后为:%sn", ret);return 0;}

6.模拟实现strncat函数

#include #include char* my_strncat(char *dest, const char *src, int count){assert(dest && src);char *ret = dest;//1.先找到的位置while (*dest++){;}dest--;//2.将源字符串追加进去(根据指定的个数)while (count--){//3.只要不是就一直追加,追加到为止if (!(*dest++ = *src++)){return ret;}}*dest = '';return ret;}int main(){char arr1[20] = "Hello ";char arr2[] = "World";printf("追加前的字符串为:%sn", arr1);char *ret = my_strncat(arr1, arr2, 8);printf("追加后的字符串为:%sn", ret);return 0;}

7.模拟实现strncmp函数

#include #include int my_strncmp(char *str1, const char *str2, int count){assert(str1 && str2);while(count&&(*str1 == *str2)){if (*str1 == '')return 0;str1++;str2++;count--;}return *str1 - *str2;}int main(){char arr1[] = "Hello";char arr2[] = "Helld";int ret = my_strncmp(arr1, arr2, 5);if (ret > 0){printf("ret = %d:arr1>arr2", ret);}else if (ret < 0){printf("ret = %d:arr1

8.模拟实现strstr函数

#include #include char* my_strstr(char* str1, const char* str2){assert(str1 && str2);char* s1;char* s2;char* cp = str1; //如果传过来的是 if (*str2 == ''){return str1;} //两种情况: // arr1-- abcdef arr1-- abbbcdef //查找arr2-- bcd arr2-- bbcwhile (*cp){s1 = cp;s2 = str2;while (*s1 != '' && *s2 != '' && *s1 == *s2){s1++;s2++;}if (*s2 == ''){return cp;}cp++;}return NULL;//没有找到的情况}int main(){char arr1[] = "abbbcdef";char arr2[] = "bcd";char* ret = my_strstr(arr1, arr2);if (ret == NULL){printf("找不到n");}else{printf("找到了,是:%sn", ret);}return 0;}

9.模拟实现memcpy函数

#include #include void* my_memcpy(void* dest, const void* src, size_t num){assert(dest && src);void* ret = dest;while (num--){*(char*)dest = *(char*)src;//强制转换为char*,是为了让其一次访问一个字节的内容dest = (char*)dest + 1;src = (char*)src + 1;}return ret;}int main(){int arr[] = { 1,2,3,4,5,6,7,8,9,10 };my_memcpy(arr, arr + 4, 4 * sizeof(int));for (int i = 0; i < 10; i++){printf("%d ", arr[i]);}return 0;}

10.模拟实现memmove函数

#include #include void* my_memmove(void* dest, const void* src, size_t count){assert(dest && src);void* ret = dest;if (dest < src){//从前向后拷贝while (count--){ //强制转换为char*,是为了让其一次访问一个字节的内容*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}}else{//从后向前拷贝while (count--){*((char*)dest + count) = *((char*)src + count);}}return ret;}int main(){int arr[] = { 1,2,3,4,5,6,7,8,9,10 };my_memmove(arr, arr + 2, 4 * sizeof(int));for (int i = 0; i < 10; i++){printf("%d ", arr[i]);}return 0;}

11.模拟实现memcmp函数

#include #include int my_memcmp(const void* ptr1, const void* ptr2, size_t num){assert(ptr1 && ptr2); //void* --- 无具体类型指针 //1.可以接受任意类型的指针 //2.但不能进行运算 //这里进行强制转换后就能够执行了while (num&&(*(char*)ptr1== *(char*)ptr2)){if (*(char*)ptr1 == ''){return 0;}(char*)ptr1+1;(char*)ptr2+1;num--;}return *(char*)ptr1 - *(char*)ptr2;}int main(){char buf1[] = "ABCDEF";char buf2[] = "ABCDGS";int ret = my_memcmp(buf1, buf2, 4 * sizeof(char));if (ret > 0){printf("buf1>buf2n");}else if (ret < 0){printf("buf1

12.模拟实现memset函数

#include #include void* my_memset(void* ptr, int val, size_t num){assert(ptr);for (int i = 0; i < num; i++){*((char*)ptr + i) = val;}}int main(){char str[] = "almost every programmer should know memset!";char ch = '-';my_memset(str, ch, 6);puts(str);return 0;}

六、总结

         以上的这些库函数大部分使用较多,深入了解并牢牢掌握其功能,对于这方面的解题会得心应手,笔者可能在模拟实现上不一定是最优解,但是可以帮助大家从了解到掌握。

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。