✨博客主页:小钱编程成长记
🎈博客专栏:进阶C语言
字符串函数(一)
- 0.前言
- 1.求字符串长度的函数
- 1.1 strlen(字符串长度)
- 2.长度不受限制的字符串函数
- 2.1 strcpy(字符串拷贝)
- 1.3 strcat(字符串追加)
- 2.3 strcmp(字符串比较)
- 总结
0.前言
小知识:
- C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在常量字符串或者字符数组中。
- 字符串常量适用于那些多它不做修改的字符串函数。
assert
断言,需要头文件assert.h 。是用来判断表达式的值不能为某值的。若表达式为假,会报错,而且会指出错误的位置,提醒你修改。
字符串函数的头文件都是string.h
1.求字符串长度的函数
1.1 strlen(字符串长度)
具体介绍链接
size_t strlen (const char *str);
注:
- 字符串已 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ )。
- 参数指向的字符串必须要以 ‘\0’ 结束,否则返回的结果为随机值。
- 注意函数的返回类型为size_t,是无符号整型( 易错 ),用%zd打印。
- 学会strlen函数的模拟实现
#include <stdio.h>
#include <string.h>
int main()
{
const char* str1 = "abcdef";
const char* str2 = "bbb";
if (strlen(str2) - strlen(str1) >= 0)//因为strlen返回类型是size_t(无符号整型),所以差也是无符号整型,无符号整型一定>=0。
{
printf(">=");
}
else
{
printf("<");
}
return 0;
}
若将返回值强转为整型,差就为-3,打印出<
strlen的模拟实现的三种方法:
- 计数器
#include <stdio.h>
#include <assert.h>
size_t my_strlen1(const char* str)//str指向的字符不需要修改,可以加上const保护字符,防止其被修改
{
assert(str);//断言(需要头文件assert.h),防止str为空指针。若为空指针(==0),会报错,而且会指出错误的位置,提醒你修改
int count = 0;
while(*str++) // == if(*str++ != \0)
{
count++;
}
return count;
}
int main()
{
char arr[] = "abcdef";
printf("%zd\n", my_strlen1(arr));//链式访问(一个函数的返回值是另一个函数的参数)
return 0;
}
- 递归
#include <stdio.h>
#include <assert.h>
size_t my_strlen2(const char* str)//str指向的字符不需要修改,可以加上const保护字符,防止其被修改
{
assert(str);//断言(需要头文件assert.h),防止str为空指针。若为空指针(==0),会报错,而且会指出错误的位置,提醒你修改
if (*str != '\0')
{
return my_strlen2(str + 1) + 1;
}
else
{
return 0;
}
}
int main()
{
char arr[] = "abcdef";
printf("%zd\n", my_strlen2(arr));//链式访问(一个函数的返回值是另一个函数的参数)
return 0;
}
- 指针 - 指针
#include <stdio.h>
#include <assert.h>
size_t my_strlen3(const char* str)//str指向的字符不需要修改,可以加上const保护字符,防止其被修改
{
assert(str);//断言(需要头文件assert.h),防止str为空指针。若为空指针(==0),会报错,而且会指出错误的位置,提醒你修改
char *start = str;
while (*str)
{
str++;
}
return str - start;
}
int main()
{
char arr[] = "abcdef";
size_t len = my_strlen3(arr);
printf("%zd\n", len);//链式访问(一个函数的返回值是另一个函数的参数)
return 0;
}
2.长度不受限制的字符串函数
不关心目标空间够不够大
不关心操作字符串的长度
2.1 strcpy(字符串拷贝)
具体介绍链接
char* strcpy(char *destination, const char *source);
介绍:
注:Copies the C string pointed by source into the array pointed by
destination, including the terminating null character (and stopping at that point).
将源指向的 C 字符串复制到目标指向的数组中,包括终止的 null(‘\0’) 字符(并在该点停止)。
- 源字符串必须以 ‘\0’ 结束。
- 会将源字符串中的 ‘\0’ 拷贝到目标空间。
- 目标空间必须足够大,以确保能存放源字符串。(否则会报错)
- 目标空间必须可变。(因为要把另一个字符串拷贝到这里)
- 返回值是目标空间的起始地址,然后通过%s来打印,%s是从给的地址开始 *解引用打印,遇到’\0’结束。
- 学会模拟实现。
模拟实现strcpy:
#include <stdio.h>
#include <assert.h>
char* my_strcpy(char* destination, const char* source)
//source指向的源字符串不需要改变,可以用const保护起来
//destination指向的目标空间必须可变,不能用const修饰
{
assert(destination && source);//断言(需要头文件assert.h),防止str为空指针。若为空指针(==0),会报错,而且会指出错误的位置,提醒你修改
char* start = destination;
while (*destination++ = *source++)
//当*source=='\0'时,整个表达式的结果为'\0',
//又因为'\0'的ASCII码(在内存中存储的I)是0,所以为假,循环结束
{
;
}
return start;
}
int main()
{
char arr1[20] = "xxxxxxxxxx";
char arr2[] = "abcdef";
my_strcpy(arr1, arr2);
printf("%s\n", arr1);//或printf("%s\n", my_strcpy);
return 0;
}
1.3 strcat(字符串追加)
具体介绍链接
char * strcat ( char * destination, const char * source );
介绍:
注:将源字符串追加到目标字符串中,源字符串的结束标志 ‘\0’ 被 source的第一个字符覆盖,并且在两者串联形成的新字符串的末尾包含一个’\0’(相当于将源字符串的’\0’也追加过去) 。
-
目标空间必须要有’\0’,保证能找到目标空间的末尾,进行追加。(编译器认为从左到右第一个’\0’是字符串的末尾)
-
源字符串必须以 ‘\0’ 结束。(在追加时源字符串的’\0’也追加过去)
-
目标空间必须有足够的大,能容纳下源字符串的内容。
-
目标空间必须可修改。
-
strcat返回的是目标空间的起始地址。
-
学会模拟实现。
模拟实现strcat :
//模拟实现strcat
#include <stdio.h>
#include <assert.h>
char* my_strcat(char* des, const char* sou)
{
char* start = des;
assert(des && sou);//断言
//1.找到目标字符串的末尾('\0')
while (*des)//找到末尾'\0'后跳出循环
{
des++;
}
//2.数据追加
while (*des++ = *sou++)//将源字符串的末尾'\0'拷贝过去的同时也结束拷贝
{
;
}
return start;
}
int main()
{
char arr1[20] = "abc";
char arr2[] = "def";
my_strcat(arr1, arr2);
printf("%s\n", arr1);//printf("%s\n", strcat(arr1, arr2));
return 0;
}
- 字符串自己给自己追加,会发生什么呢?
- 若用刚刚自己模拟的函数追加,会死循环。
2. 用vs自带的库函数却能正常追加
这说明vs库函数中strcat的实现方式和自己的实现方式有所差异,其实不同编译器对库函数的实现方式都可能有所差异。所以stccat在VS上能自己追加自己,但其他编译器不一定可以。
若非要自己追加自己,建议使用strncat。
2.3 strcmp(字符串比较)
具体介绍链接
int strcmp ( const char * str1, const char * str2 );
介绍:
C语言标准规定:
- 此函数开始比较每个字符串的第一个字符,如果它们相等,则继续向下比较,直到字符不同或达到终止空字符(‘\0’)。
- 比较的不是长度,而是对应位置上字符的大小(ASCII码,因为字符在内存中是以ASCII码的形式存储的)
返回值(整型) | 解释 |
---|---|
大于 0 | 第一个字符串大于第二个字符串 |
0 | 第一个字符串等于第二个字符串 |
小于 0 | 第一个字符串小于第二个字符串 |
不同的编译器具体返回的值不同
模拟实现strcmp :
//模拟实现strcmp
#include <stdio.h>
#include <assert.h>
int my_strcmp(const char* str1, const char* str2)
{
assert(str1 && str2);//断言,防止为空指针
while (*str1 == *str2)
{
if (*str1 == '\0')//同时为'\0'时,两个字符串才相等
{
return 0;
}
str1++;
str2++;
}
return *str1 - *str2;
//或
//if (*str1 > *str2)
//{
// return 1;
//}
//else
//{
// return -1;
//}
}
int main()
{
char arr1[] = "abcdef";
char arr2[] = "abp";
if (my_strcmp(arr1, arr2) > 0)
{
printf(">\n");
}
else if(my_strcmp(arr1, arr2) == 0)
{
printf("=\n");
}
else
{
printf("<\n");
}
return 0;
}
从这分成两篇博文:
总结
我们一起学习了计算字符串长度的函数和长度不受限制的字符串函数。
感谢大家的阅读,大家一起进步!
点赞收藏加关注,C语言学习不迷路!