模拟实现函数
长度不受限制的字符串函数
函数介绍:
一、strlen函数
size_t strlen(const char* str);
功能:求字符串的长度(不包括\0)
- 字符串是以‘\0’结尾的。strlen返回的是‘\0’前出现的字符的个数,不包括‘\0’的长度。
- 参数指向的字符要以‘\0’结尾
- 注意函数的返回值是size_t,是无符号的**(易错)**
strlen模拟实现
1、计数器方法实现
int my_strlen(const char *p){
assert(*p);
int count=0;
while (*p){//遇到'\0'结束
count++;
p++;
}
return count;
}
int main(){
char arr[] = "abcdefg";
int num = 0;
num = my_strlen(arr);
printf("%d", num);
system("pause");
return 0;
}
2、递归方法实现
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <Windows.h>
#include <assert.h>
//递归方法实现
int my_strlen(const char *p){
assert(p);//排除空指针
int num = 0;
if (*p!='\0'){
return 1+my_strlen(++p);//递归,直到找当字符串中的'\0'
}
else {
return 0;//找到\0,但是strlen函数计算字符串长度不把'\0'算入内,
}
}
int main(){
char *arr = "abcdefg";
int num = 0;
num = my_strlen(arr);
printf("%d", num);
system("pause");
return 0;
}
3、指针减指针方法实现
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <Windows.h>
#include <assert.h>
//指针减指针方法实现
int my_strlen(const char *p){
assert(p);//排除空指针
char *i = p;
while (*i != '\0'){
i++;//让指针挪到字符串最后一个位置,'\0'前一个位置。
}
return i - p;//指针减去指针所得的值是他们之间相隔的个数。
}
int main(){
char *arr = "abcdefg";
int num = 0;
num = my_strlen(arr);
printf("%d", num);
system("pause");
return 0;
}
注:因为strlen函数返回的是个无符号数,如果出现下列情况
return strlen("abc")-atrlen("abcdef");
本来结果应该是-3,但是由于返回的是个无符号数,所以符号位的1会被认为是数值,那么返回的数字就是个大于0的数。这是strlen这个函数的易错点。
二、模拟实现strcpy函数
char* strcpy(char* destination ,const char* source);
功能:把从source地址开始的且含有NULL的字符串复制到以destination地址开始的字符空间里面去。
- 源字符串必须以’\0’结束
- 会将源字符串中的’\0’拷贝到目标空间去。
- 目标空间必须足够的大,以确保能够存放源字符串。
- 目标地址必须可变。
函数实现:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <Windows.h>
#include <assert.h>
//指针减指针方法实现
int my_strlen(const char *p){
assert(p);//排除空指针
char *i = p;
while (*i != '\0'){
i++;//让指针挪到字符串最后一个位置,'\0'前一个位置。
}
return i - p;//指针减去指针所得的值是他们之间相隔的个数。
}
//strcpy函数实现
void my_strcpy(char *dest,const char *src){//因为是把arr2里的字符串复制到arr1中,所以arrr2中的字符串不需要修改,为了防止程序出现了错误,加上const(不允许修改)
assert(dest!=NULL);//判断是否为空指针,如果为控股指针则打印出错误信息
assert(src!=NULL);
if (my_strlen(dest) - my_strlen(src) < 0){//当目的字符数组的长度小于源字符数组长度,则打印错误提示,退出my_strcpy函数
printf("目的字符数组的长度小于源字符数组长度");
return ;
}
else{
while (*src != '\0'){//依次将arr2中的字符复制到arr1中,包括'\0'
*dest = *src;
dest++;
src++;
}
*dest = *src;
return;
}
}
int main(){
char arr1[] = "abcdef";
char arr2[] = "qwe";
my_strcpy(arr1, arr2);
printf("%s", arr1);
system("pause");
return 0;
}
my_strcpy函数部分还可以更加精炼一点
//因为是把arr2里的字符串复制到arr1中,所以arrr2中的字符串不需要修改,为了防止程序出现了错误,加上const(不允许修改)
void my_strcpy(char *dest,const char *src){
//判断是否为空指针,如果为控股指针则打印出错误信息
assert(dest!=NULL);
assert(src!=NULL);
//当目的字符数组的长度小于源字符数组长度,则打印错误提示,退出my_strcpy函数
if (my_strlen(dest) - my_strlen(src) < 0){
printf("目的字符数组的长度小于源字符数组长度");
return ;
}
else{
//依次将arr2中的字符复制到arr1中,包括'\0'
while (*dest++ = *src++);
*dest = *src;
return;
}
}
三、模拟实现strcat函数
strcat(char dest,const char src);
功能:将源字符数组追加到目的字符数组后面。
- 目标字符数组的空间必须足够大,能容纳源字符串的内容。
- 源字符串必须以’\0’结束。
- 目标空间必须可修改。
1、strcat函数模拟实现
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <Windows.h>
#include <assert.h>
#define NUM 30
//strcat函数模拟实现
void my_strcat(char *dest, const char *src){
//assert(dest != NULL);//判断字符指针不能为空指针
assert(src != NULL);
if ( NUM< ( strlen(dest) + strlen(src) ) ){//如果目标空间容纳不下源字符串的追加,则退出函数
printf("目标字符数组空间过小");
return;
}
else{
while (*dest != '\0'){//找到目的字符数组的末尾
dest++;
}
while (*src != '\0'){//开始追加
*dest++ = *src++;
}
*dest = *src;//把源字符串中的'\0'放进目标字符数组中
return;
}
}
int main(){
char arr1[NUM] = "abcdef";
char arr2[] = "qwe";
my_strcat(arr1, arr2);
printf("%s", arr1);
system("pause");
return 0;
}
2、strcat函数给自己追加会发生什么呢?
如果strcat函数给自己追加的话,那么原来的‘\0’的位置会被修改,就可能会导致函数死循环。
三、模拟实现strcmp 函数
int strcmp(const char* str1,const char* str2);
标准规定
- 第一个字符串大于第二个字符串,则返回大于0的数字
- 第一个字符串等于第二个字符串,则返回0
- 第一个字符串小于第二个字符串则返回小于0的数字
注:这里比较的是ascii码值的大小。
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <Windows.h>
#include <assert.h>
//strcmp函数实现
int my_strcmp(const char* p1,const char *p2){
assert(p1);
assert(p2);
while ((*p1) == (*p2)&&(*p1!='\0')){//找到第一个不相等的字符
p1++;
p2++;
}
if ((*p1) == (*p2)){//如果最后一个字符相等且等于'\0' ,则代表两个字符串完全相等,返回0
return 0;
}
else if ((*p1) > (*p2)){//第一个字符串大于第二个字符串,则返回1
return 1;
}
else if ((*p1) < (*p2)){//第一个字符串小于第二个字符串,则返回-1
return -1;
}
}
int main(){
char arr1[NUM] = "abcdef";
char arr2[] = "abc";
int ret = my_strcmp(arr1, arr2);
printf("%d", ret);
system("pause");
return 0;
}
结尾:上述都是长度不受限的字符串函数,对字符串的操作都是遇到了’\0’停止,这样就有可能发生越界访问,产生不安全。