C语言之字符串函数
文章目录
- C语言之字符串函数
- 1. strlen的使用和模拟实现
- 1.1 strlen的使用
- 1.2 strlen的模拟实现
- 2. strcpy的使用和模拟实现
- 2.1 strcpy的使用
- 2.2 strncpy的使用
- 2.3 strcpy的模拟实现
- 3. strcat的使用和模拟实现
- 3.1 strcat的使用
- 3.2 strncat
- 3.3 strcat的模拟实现
- 4. strcmp 的使⽤和模拟实现
- 4.1 strcmp的使用
- 4.2 strncmp
- 4.3 strcmp的模拟实现
1. strlen的使用和模拟实现
• 字符串以 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前⾯出现的字符个数(不包含 ‘\0’ )。
• 参数指向的字符串必须要以 ‘\0’ 结束。
• 注意函数的返回值为size_t,是⽆符号的
1.1 strlen的使用
strlen函数的声明
size_t strlen ( const char * str );
strlen函数是用来计算字符串的长度的,计算的是 ’ \0 '之前字符的总个数
例子:
#include <stdio.h>
#include <string.h> //使用strlen需要包含的头文件
int main()
{
char arr[] = "abcdef";
strlen(arr);
printf("%s\n", arr);
return 0;
}
运行结果为 6
与sizeof不同的是,sizeof计算的数组中的元素个数包括’ \0 ',详细可看sizeof和strlen
1.2 strlen的模拟实现
给strlen传一个地址,然后它就会计算’\0’之前字符的总个数,并且返回值是size_t即无符号整型
代码如下:
#include <stdio.h>
#include <string.h>
#include <assert.h>
size_t my_strlen1(const char* str)//通过计数器的方式
{
assert(str != NULL); //assert断言,判断传入的地址是否为空指针
int count = 0;
while (*str != '\0')//str中的内容不为'\0'的时候进入循环
{
count++;
str++;
}
return count;
}
size_t my_strlen2(const char* str)//指针 - 指针 计算的是两个指针之间的元素个数
{
char* start = str;
assert(str != NULL);
while (*str != '\0')
{
str++;
}
return str - start;
}
size_t my_strlen3(const char* str) //递归的方式
//假设传入一个字符串"abc"
//递的过程
//第一次进入函数,*str == a 调用本身1 + my_strlen3("bc")
//第二次进入函数,*str == b 调用本身1 + 1 + my_strlen3("c")
//第三次进入函数,*str == c 调用本身1 + 1 + 1 + my_strlen3(" ")
//第四次进入函数,*str == '\0' ,开始归
//第四次返回一个0,0 + 1 + 1 + 1
{
if (*str == '\0')
return 0;
else
return 1 + my_strlen3(str+1);
}
int main()
{
char arr[] = "abcdef";
size_t len1 = my_strlen1(arr);
size_t len2 = my_strlen2(arr);
size_t len3 = my_strlen3(arr);
printf("%zd\n",len1 );
printf("%zd\n",len2 );
printf("%zd\n",len3 );
return 0;
}
以上为三种strlen的模拟实现,代码运行如下:
2. strcpy的使用和模拟实现
• 源字符串必须以 ‘\0’ 结束。
• 会将源字符串中的 ‘\0’ 拷⻉到⽬标空间。
• ⽬标空间必须⾜够⼤,以确保能存放源字符串。
• ⽬标空间必须可修改。
2.1 strcpy的使用
函数声明如下:
char * strcpy ( char * destination, const char * source );
strcpy用来将source中的字符串,拷贝到destination中去
例子:
#include <stdio.h>
#include <string.h>
int main()
{
char arr1[20] = { "xxxxxxxx"};
char arr2[] = "abc";
strcpy(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
代码运行结果如下:
可以看到strcpy将arr2中的元素拷贝了一份到arr1中,同时在后面加上了一个’\0’,所以abc之后的x不会打印
2.2 strncpy的使用
要想拷贝指定数量的元素可以使用strncpy
函数声明如下:
char * strncpy ( char * destination, const char * source, size_t num );
和strcpy差不多,只是多了一个size_t num这个形参,这个是用来拷贝指定数量的
例子:
#include <stdio.h>
#include <string.h>
int main()
{
char arr1[20] = { 0 };
char arr2[] = "abcdef";
strncpy(arr1, arr2,3);
printf("%s\n", arr1);
return 0;
}
代码运行结果如下:
只会将arr2中前面3个元素拷贝到arr1中
2.3 strcpy的模拟实现
strcpy是用来将两个数组中下标一致的元素,将source中的字符拷贝到destination中去,一个一个拷贝
代码如下:
写法一:
char* my_strcpy(char* dest, char* src)
{
char* ret = dest;
assert(dest != NULL);
assert(src != NULL);
while (*src) //当src中的元素不为'\0'时进入循环
{
*dest = *src; //将src中的值赋给dest
*src++; //src++,找到下一个元素的地址
*dest++; //dest++,找到下一个元素的地址
}
*dest = *src; //由于当src中的元素为'\0'时,循环结束了,'\0'不会赋值到dest中去,使用最后将'\0'赋值给dest
return ret;
}
int main()
{
char arr1[20] = { 0 };
char arr2[] = "abcdef";
my_strcpy(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
写法二:
```c
#include <stdio.h>
#include <string.h>
#include <assert.h>
char* my_strcpy(char* dest, char* src)
{
char* ret = dest;
assert(dest != NULL); //判断传入的指针不是空指针
assert(src != NULL);
while (*dest++ = *src++)
// *dest = *src 将src的值拷贝到dest
//拷贝完之后,通过指针偏移找到下一个元素
//++是先使用后加
{
//因为只是拷贝元素,while里面不做什么事
//使用while必须跟一个语句,使用加上了一个空语句
//使用大括号里边可以不加,但是加上会更清晰一点
;
}
return ret;
}
int main()
{
char arr1[20] = { 0 };
char arr2[] = "abcdef";
my_strcpy(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
3. strcat的使用和模拟实现
• 源字符串必须以 ‘\0’ 结束。
• ⽬标字符串中也得有 \0 ,否则没办法知道追加从哪⾥开始。
• ⽬标空间必须有⾜够的⼤,能容纳下源字符串的内容。
• ⽬标空间必须可修改。
3.1 strcat的使用
函数声明如下:
char * strcat ( char * destination, const char * source );
strcat是将source中的元素追加到destination之后,可以理解为两个字符串的拼接
例子如下:
#include <stdio.h>
#include <string.h>
int main()
{
char arr1[20] = "hello ";
char arr2[] = "world";
strcat(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
3.2 strncat
要想追加指定元素,可以使用strncat
代码如下:
#include <stdio.h>
#include <string.h>
int main()
{
char arr1[20] = "hello ";
char arr2[] = "worldabcdef";
strncat(arr1, arr2,5);
printf("%s\n", arr1);
return 0;
}
运行结果如下:
只会将arr2中前五个元素追加到arr1中去,之后的元素则不会追加
3.3 strcat的模拟实现
strcat是先找到destination中的’\0’,然后再其后面开始追加元素
代码如下:
include <stdio.h>
#include <string.h>
#include <assert.h>
char* my_strcat(char* dest, const char* src)
{
char* ret = dest;
assert(dest && src);
while (*dest) //当dest中的元素不为'\0'时,dest++,找到'\0'的位置
{
dest++;
}
while (*dest++ = *src++) //从'\0'之后的位置开始将src中的元素赋值给dest
{
;
}
return ret;
}
int main()
{
char arr1[20] = "hello ";
char arr2[] = "world";
my_strcat(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
4. strcmp 的使⽤和模拟实现
◦ 第⼀个字符串⼤于第⼆个字符串,则返回⼤于0的数字
◦ 第⼀个字符串等于第⼆个字符串,则返回0
◦ 第⼀个字符串⼩于第⼆个字符串,则返回⼩于0的数字
◦ 比较的是两个元素的ASCII值
4.1 strcmp的使用
函数声明如下:
int strcmp ( const char * str1, const char * str2 );
比较str1和str2中下标相同元素的ASCII值
如果第一个元素相等时,则比较下一对元素的ASCII值
大于则返回一个大于零的值
小于则返回一个小于零的值
等于则返回零
例子:
#include <stdio.h>
#include <string.h>
int main()
{
char arr1[] = "abcd";
char arr2[] = "abq";
int ret = strcmp(arr1, arr2);
if (ret > 0)
printf("大于\n");
else if (ret == 0)
printf("等于\n");
else
printf("小于\n");
return 0;
}
由于前两个元素相同,所以比较第三个元素的ASCII值
q的ASCII值大于c的ASCII值
所以会打印小于
4.2 strncmp
可以指定比较的元素个数
代码如下:
#include <stdio.h>
#include <string.h>
int main()
{
char arr1[] = "abcd";
char arr2[] = "abq";
int ret = strncmp(arr1, arr2,2);
if (ret > 0)
printf("大于\n");
else if (ret == 0)
printf("等于\n");
else
printf("小于\n");
return 0;
}
由于只比较了前两个元素的ASCII值,前两个元素相等
所以会打印等于
4.3 strcmp的模拟实现
代码如下:
#include <stdio.h>
#include <string.h>
#include <assert.h>
int my_strcmp(const char* str1, const char* str2)
{
assert(str1 && str2);
while (*str1 == *str2)
{
if (*str1 == '\0')
return 0;
str1++;
str2++;
}
return *str1 - *str2;
}
int main()
{
char arr1[] = "abcd";
char arr2[] = "abq";
int ret = my_strcmp(arr1, arr2);
if (ret > 0)
printf("大于\n");
else if (ret == 0)
printf("等于\n");
else
printf("小于\n");
return 0;
}