前言
我们在之前C语言初阶的时候,用到了strlen之类的字符串函数,我们也知道字符串函数的头文件为<string.h>,在这里我们,继续向大家介绍其他字符串函数,以及模拟实现这些字符串函数
字符串函数有很多种,我们接下来介绍的是比较常用的几种函数。
一、字符串函数存在的意义
C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的。
1.字符串通常放在常量字符串中或者字符数组中。
2.字符串常量 适用于那些对它不做修改的字符串函数
二、函数介绍
2.1 strlen
size_t strlen ( const char * str ); 求得字符串长度
1.字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0' )
2.参数指向的字符串必须要以 '\0' 结束。
3.注意函数的返回值为size_t,是无符号的( 易错 )
代码实现:
模拟strlen函数:
#include<stdio.h> #include<string.h> #include<assert.h> int my_strlen1(const char* src) { assert(src);//断言 int count = 0; while (*src++) { count++; } return count; } //使用递归的方法 int my_strlen2(const char* src) { if (*src==0) { return 0; } else { /* src++;*/ return 1 + my_strlen2(++src); } } //使用指针-指针 (得到是之间的元素个数) int my_strlen3(const char* src) { char* ret = src; while (*src) { src++; } return src - ret; } int main() { char arr[] = "abcdef"; int len = my_strlen3(arr); printf("%d\n", len); return 0; }
2.2 strcpy
char* strcpy(char * destination, const char * source );
拷贝函数,将source内容拷贝到destination上。
函数特性:
1.源字符串必须以 '\0' 结束。 (src有'\0')
2.会将源字符串中的 '\0' 拷贝到目标空间。 ('\0'会拷贝到dest上)
3.目标空间必须足够大,以确保能存放源字符串。 (dest要足够大,大于等于src)
4.目标空间必须可变 (strcpy函数修改的是dest,所以dest能被修改)
代码演示:
模拟strcpy函数:
#include<stdio.h> #include<string.h> #include<assert.h> char *my_strcpy(char* dest, const char* src) { assert(dest && src); char* ret = dest; while (*dest++ = *src++) { ; } return ret; } int main() { char arr1[10] = "123456789"; char arr2[] = "abcdef"; my_strcpy(arr1, arr2); printf("%s\n", arr1); return 0; }
2.3 strcat
char * strcat ( char * destination, const char * source );
覆盖destination上的' \0 '上继续加上source的内容 ,追加字符串函数
函数特性:
1.源字符串必须以 '\0' 结束。 (这是因为strcat之后,dest的'\0'被src第一个元素覆盖)
2.目标空间必须有足够的大,能容纳下源字符串的内容。 (dest大于等于src+dest空间)
3.目标空间必须可修改。 (dest是会被改变的)
函数实现:
模拟strcat函数:
#include<stdio.h> #include<string.h> #include<assert.h> char*my_strcat(char* dest, const char* src) { assert(dest && src); //断言 //我们需要的是找到dest的'\0'位置,在这个后面开始赋值 char* ret = dest; while (*++dest) { //找'\0'的时候 先++ ,这样避免算进去'\0' ; } while (*dest++ = *src++) { ; } return ret; } int main() { char arr1[20] = "hello "; char arr2[] = "world!"; my_strcat(arr1, arr2); printf("%s\n", arr1); return 0; }
这边还有一个问题,供大家思考,如果是字符串自己给自己追加,会发生什么?
所以我们得出结论,字符串不能自己追加自己,会死循环 !!!
2.4 strcmp
int strcmp ( const char * str1, const char * str2 );
strcmp函数:是对字符串进行比较的函数。
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字
代码演示:
模拟strcmp函数
#include<stdio.h> #include<string.h> #include<assert.h> int my_strcmp(const char* dest, const char* src) { assert(dest && src);//断言 while (*dest++ == *src++&&*dest!='\0'&&*src!='\0') { //要保证的是,出来之后的dest和src的地址,是起码有一方到'\0'的地址 //所以 *dest!='\0'&&*src!='\0' //这样就可以停止了,对这样的进行判断 ; } if (*dest < *src) { return -1; } else if (*dest > *src) { return 1; } else { return 0; } } int main() { char arr1[]="abcdef"; char arr2[] = "abc"; char arr3[] = "abc"; char arr4[] = "a"; int num1=my_strcmp(arr1, arr2); printf("%d\n", num1); int num2 = my_strcmp(arr3, arr2); printf("%d\n", num2); int num3 = my_strcmp(arr4, arr2); printf("%d\n", num3); return 0; }
2.5 strncpy
char * strncpy ( char * destination, const char * source, size_t num );
与strcpy函数相比,多个n,表示多个参数num,意味拷贝num个字节的数据
代码演示:
代码演示:
#include<stdio.h> #include<string.h> #include<assert.h> char* my_strncpy(char* dest, const char* src,size_t num) { assert(dest && src); char* ret = dest; int count = 0; while (*dest++ = *src++) { count++; if (count == num) { break; } } return ret; } int main() { char arr1[10] = "123456789"; char arr2[] = "abcdef"; my_strncpy(arr1, arr2,3); printf("%s\n", arr1); return 0; }
对于这样的限制字节的字符串函数,模拟实现,只需要在相应的位置上加上num的限制即可
2.6 strncat
char * strncat ( char * destination, const char * source, size_t num );
代码演示:
模拟实现strncat:
#include<stdio.h> #include<string.h> #include<assert.h> char* my_strncat(char* dest, const char* src,size_t num) { assert(dest && src); //断言 //我们需要的是找到dest的'\0'位置,在这个后面开始赋值 char* ret = dest; while (*++dest) { //找'\0'的时候 先++ ,这样避免算进去'\0' ; } int count = 0; while (*dest++ = *src++) { count++; if (count == num) { break; } } return ret; } int main() { char arr1[20] = "hello "; char arr2[] = "world!"; my_strncat(arr1, arr2,3); printf("%s\n", arr1); return 0; }
2.7 strcmp
int strncmp ( const char * str1, const char * str2, size_t num );
代码演示:
模拟strncmp:
#include<stdio.h> #include<string.h> #include<assert.h> int my_strncmp(const char* dest, const char* src,size_t num) { assert(dest && src);//断言 int count = 0; while (*dest == *src && *dest != '\0' && *src != '\0') { //要保证的是,出来之后的dest和src的地址,是起码有一方到'\0'的地址 //所以 *dest!='\0'&&*src!='\0' //这样就可以停止了,对这样的进行判断 count++; if (count == num) { break; } dest++; src++; } if (*dest < *src) { return -1; } else if (*dest > *src) { return 1; } else { return 0; } } int main() { char arr1[]="abcdef"; char arr2[] = "abc"; char arr3[] = "abc"; char arr4[] = "a"; int num1=my_strncmp(arr1, arr2,1); printf("%d\n", num1); int num2 = my_strncmp(arr3, arr2,1); printf("%d\n", num2); int num3 = my_strncmp(arr4, arr2,1); printf("%d\n", num3); return 0; }