一、strlen函数
size_t strlen(const char *str);
注:(1)字符串以'\0'为结束标志,strlen函数返回的是在字符串中'\0'前面出现的字符个数
(2)参数指向的字符串必须要以'\0'结束
(3)函数的返回值是size_t型,该型是无符号整型
1.分析
#include<stdio.h>
#include<assert.h>
size_t my_strlen(const char* str)
{
assert(str);//对该指针进行断言,判断是否为空指针,可有效避免访问到空指针
size_t count = 0;
while (*str != '\0')
{
count++;
str++;
}
return count;
}
int main()
{
char arr[] = "abcdef";
size_t n = my_strlen(arr);
printf("字符串长度=%u\n", n);
return 0;
}
2.代码实现
#include<stdio.h>
#include<assert.h>
size_t my_strlen(const char* str)
{
assert(str);//对该指针进行断言,判断是否为空指针,可有效避免访问到空指针
size_t count = 0;
while (*str != '\0')
{
count++;
str++;
}
return count;
}
int main()
{
char arr[] = "abcdef";
size_t n = my_strlen(arr);
printf("字符串长度=%u\n", n);
return 0;
}
3.仿真验证
二、 strcpy函数
char * strcpy(char * destination,const char *source)
注:(1)源字符串必须以'\0'结束
(2)会将源字符串中的'\0'拷贝到目标空间(可用vs中的监视器观测)
(3)目标空间必须足够大,以确保能够存放源字符串
(4)目标空间必须可变(指目标空间中不能有常量字符串)
1.分析
#include<stdio.h>
#include<assert.h>
char *my_strcpy(char* dest, const char* src)//在源字符串前加const,保证该字符串不轻易被改变,避免发生错误
{
assert(dest);
assert(src);
char* ret = dest;//将目标空间的地址保存下来
while (*src)//当src为正常字符时进行循环,当src指向'\0'时循环结束
{
*dest++ = *src++;
}
*dest = *src;//按照定义将'\0'进行存储
return ret;//按照strcpy函数的定义,返回目标空间的地址
}
int main()
{
char arr1[] = "abcdef";
char arr2[20] = { 0 };
my_strcpy(arr2, arr1);
printf("%s\n", arr2);
return 0;
}
2.代码实现
#include<stdio.h>
#include<assert.h>
char *my_strcpy(char* dest, const char* src)//在源字符串前加const,保证该字符串不轻易被改变,避免发生错误
{
assert(dest);
assert(src);
char* ret = dest;//将目标空间的地址保存下来
while (*src)//当src为正常字符时进行循环,当src指向'\0'时循环结束
{
*dest++ = *src++;
}
*dest = *src;//按照定义将'\0'进行存储
return ret;//按照strcpy函数的定义,返回目标空间的地址
}
int main()
{
char arr1[] = "abcdef";
char arr2[20] = { 0 };
my_strcpy(arr2, arr1);
printf("%s\n", arr2);
return 0;
}
3.仿真验证
三、strcat函数(字符串追加)
char * strcat(char *destination ,const char *source);
注:(1)源字符串必须以'\0'结束
(2)目标空间必须有足够的大,能容纳下源字符串的内容
(3)目标空间必须可修改
(4)字符串不可自己给自己追加(原因:字符串追加时会将源字符串中的'\0'覆盖,导致拷贝时字符串中不存在'\0',程序难以停止下来。在一些编译器上可能成功,但是实际操作中还是要避免这种情况的出现)
1.分析
#include<stdio.h>
char* my_strcat(char* dest, const char* src)
{
char* ret = dest;
//该函数操作步骤(1)找到目标字符串的结尾'\0' (2)用strcpy类似的方法进行拷贝
while (*dest != '\0')
{
dest++;
}
while (*dest++ = *src++)//将src指向的内容幅值给dest指针指向的空间,直到src指向'\0',循环结束
{
;
}
return ret;//按照strcat函数的第一,返回目标空间的地址
}
int main()
{
char arr1[20] = "hello ";
my_strcat(arr1, "world");//表示将“world”拷贝到“hello”之后
printf("%s\n", arr1);
}
2.代码实现
#include<stdio.h>
char* my_strcat(char* dest, const char* src)
{
char* ret = dest;
//该函数操作步骤(1)找到目标字符串的结尾'\0' (2)用strcpy类似的方法进行拷贝
while (*dest != '\0')
{
dest++;
}
while (*dest++ = *src++)//将src指向的内容幅值给dest指针指向的空间,直到src指向'\0',循环结束
{
;
}
return ret;//按照strcat函数的第一,返回目标空间的地址
}
int main()
{
char arr1[20] = "hello ";
my_strcat(arr1, "world");//表示将“world”拷贝到“hello”之后
printf("%s\n", arr1);
}
3.仿真验证
四、strcmp函数(字符串比较)
int strcmp(const char* str1,const char*str2);
注:(1)第一个字符串大于第二个字符串,则返回大于0的数字;
(2)第一个字符串等于第二个字符串,则返回0;
(3)第一个字符串小于第二个字符串,则返回小于0的数字;
(4)以上三种比较,均比较的是字符串内部字符的ASCII码值
1.分析
#include<stdio.h>
#include<assert.h>
int my_strcmp(const char*str1,const char*str2)//本程序中这两个指针不需要进行修改,所以添加const进行保护
{
assert(str1 && str2);//避免访问到空指针发生错误
while (*str1 == *str2)
{
if (*str1 == '\0')//若循环直到'\0'还满足相等条件,那么需要判断是否到达了'\0',避免形成越界访问
return 0;
str1++;
str2++;
}
/*if (*str1 > *str2)
return 1;
else
return -1;*/
return (*str1 - *str2);//对该代码进行优化,直接返回两指针指向两个值的差,从大于0和小于0进行比较,更加贴近该函数的定义
}
int main()
{
char arr1[] = "abcd";
char arr2[] = "abc";
int ret = my_strcmp(arr1, arr2);
if (ret < 0)
printf("小于\n");
else if (ret == 0)
printf("等于\n");
else
printf("大于\n");
}
2.代码实现
#include<stdio.h>
#include<assert.h>
int my_strcmp(const char*str1,const char*str2)//本程序中这两个指针不需要进行修改,所以添加const进行保护
{
assert(str1 && str2);//避免访问到空指针发生错误
while (*str1 == *str2)
{
if (*str1 == '\0')//若循环直到'\0'还满足相等条件,那么需要判断是否到达了'\0',避免形成越界访问
return 0;
str1++;
str2++;
}
/*if (*str1 > *str2)
return 1;
else
return -1;*/
return (*str1 - *str2);//对该代码进行优化,直接返回两指针指向两个值的差,从大于0和小于0进行比较,更加贴近该函数的定义
}
int main()
{
char arr1[] = "abcd";
char arr2[] = "abc";
int ret = my_strcmp(arr1, arr2);
if (ret < 0)
printf("小于\n");
else if (ret == 0)
printf("等于\n");
else
printf("大于\n");
}
3.仿真验证
五、strstr函数(查找字符串函数)
char *strstr(const char*str1,const char*str2);//返回目标函数中找到的字符串的首地址
1.分析
#include<stdio.h>
#include<assert.h>
char* my_strstr(const char* str1, const char* str2)
{
assert(str1 && str2);
const char* s1 = str1;
const char* s2 = str2;
const char* p = str1;//举例说明:若题目要求在"abbcd"中寻找"bcd",那么指针扫描到第一个b处后会理所应当向后推进检测是否满足"bcd"
//若发现并不符合时,需要有一个新指针标记第一个b所处的位置,从而向后推进,否则会陷入死循环
while (*p)
{
s1 = p;
s2 = str2;
while (*s1!='\0'&&*s2!='\0'&& * s1 == *s2)
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return (char*)p;//说明str2已经遍历结束,字符串已经找到,返回目标函数中所找字符串首地址即可
}
p++;
}
return(NULL);//直到最后都没有返回指针,说明并没有找到目标子串
}
int main()
{
char arr1[] = "jia you peng you";
char arr2[] = "peng you";
char* ret = my_strstr(arr1, arr2);//表示在"jia you peng you"中寻找"peng you"
if (ret == NULL)
{
printf("子串不存在\n");
}
else
{
printf("%s\n", ret);
}
}
2.代码实现
#include<stdio.h>
#include<assert.h>
char* my_strstr(const char* str1, const char* str2)
{
assert(str1 && str2);
const char* s1 = str1;
const char* s2 = str2;
const char* p = str1;//举例说明:若题目要求在"abbcd"中寻找"bcd",那么指针扫描到第一个b处后会理所应当向后推进检测是否满足"bcd"
//若发现并不符合时,需要有一个新指针标记第一个b所处的位置,从而向后推进,否则会陷入死循环
while (*p)
{
s1 = p;
s2 = str2;
while (*s1!='\0'&&*s2!='\0'&& * s1 == *s2)
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return (char*)p;//说明str2已经遍历结束,字符串已经找到,返回目标函数中所找字符串首地址即可
}
p++;
}
return(NULL);//直到最后都没有返回指针,说明并没有找到目标子串
}
int main()
{
char arr1[] = "jia you peng you";
char arr2[] = "peng you";
char* ret = my_strstr(arr1, arr2);//表示在"jia you peng you"中寻找"peng you"
if (ret == NULL)
{
printf("子串不存在\n");
}
else
{
printf("%s\n", ret);
}
}