C语言——各类字符串函数模拟(包括strlen,strcpy,strncpy,strcmp,strcat,strncat,strstr,atoi函数)

目录

一.strlen函数

1.函数简介

2.模拟代码

什么是断言

3.对比截图 

​二.strcpy函数

1.函数简介

2.模拟代码

3.对比截图 

4.注意

三.strncpy函数

1.函数简介

2.模拟代码

3.对比截图

四.strcmp函数

        1.函数简介

2.模拟代码

3.对比截图 

​五.strcat函数

1.函数简介

2.模拟代码

3.对比截图 

六.strncat函数

1.函数简介

2.模拟代码

3.对比截图

七.strstr函数

1.函数简介

2.模拟代码

3.对比截图 

4.注意

八.atoi函数

1.函数简介

2.模拟代码

3.对比截图

4.注意


一.strlen函数

1.函数简介

strlen所作的是一个计数器的工作,它从内存的某个位置(可以是字符串开头,中间某个位置,甚至是某个不确定的内存区域)开始扫描,直到碰到第一个字符串结束符'\0'为止,然后返回计数器值(长度不包含'\0')。

原型声明extern unsinfned int strlen(char *s);

头文件:#include <string.h> 和 #include <stdio.h>。

功能:计算给定字符串的(unsigned int型)长度,不包括'\0'在内。

说明:返回s的长度,不包括结束符NULL。

2.模拟代码

什么是断言:

断言概念:编写代码时,我们总是会做出一些假设,断言就是用于在代码中捕捉这些假设,可以将断言看作是异常处理的一种高级形式。断言表示为一些布尔表达式,程序员相信在程序中的某个特定点该表达式值为真。可以在任何时候启用和禁用断言验证,因此可以在测试时启用断言,而在部署时禁用断言。

用法void assert(int test);

头文件#include<assert.h>

作用:如果它的条件返回错误,则终止程序执行

注意:assert是宏,而不是函数。

#include<stdio.h>
#include<string.h>
#include<assert.h>

int mystrlen(char *str){
	assert((str != NULL));//断言
	int count = 0;//计数器,记录字符串长度
	while (*str != '\0'){
		str++;
		count++;
	}
	return count;
}

void main(){
	char str[10] = "ajfwiwegd";
	printf("%d\n", mystrlen(str));
	printf("%d\n", strlen(str));
}

3.对比截图 

​二.strcpy函数

1.函数简介

将后一字符串复制到前一字符串的空间。

原型声明char *strcpy(char* dest, const char *src);

头文件:#include <string.h> 和 #include <stdio.h>。

功能:把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间

说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。

返回指向dest的指针

2.模拟代码

#include<stdio.h>
#include<string.h>
#include<assert.h>

char *mystrcpy(char *dest, const char *src){
	assert((dest != NULL) && (src != NULL));//断言
	char *tmp = dest;//保存dest的起始地址,用于返回
	while (*src != '\0'){
		*dest = *src;
		src++;
		dest++;
	}
	*dest = '\0';
	return tmp;
}

void main(){
	char src[10] = "ajfwiwegd";
	char dest[20] = { 0 };
	printf("%s\n", mystrcpy(dest,src));
	printf("%s\n", strcpy(dest,src));
}

3.对比截图 

4.注意

        一定要设置一个指针tmp用于保存dest的起始地址,而不能直接返回dest,因为此时dest已经指向字符串末尾,而不是起始位置。模拟strcat函数时也要注意这个问题。

三.strncpy函数

1.函数简介

原型声明char *strncpy(char *dest, const char *src, int n);

参数

  • dest:表示复制的目标字符数组;
  • src:表示复制的源字符数组;
  • n:表示复制的字符串长度。

头文件:#include <string.h> 和 #include <stdio.h>。

功能:把src所指向的字符串中以src地址开始的前n个字节复制到dest所指的数组中,并返回被复制后的dest。

说明

与strcpy的区别

1.strcpy只是复制字符串,但不限制复制的数量,很容易造成缓冲溢出。strncpy要安全一些。

2.strncpy能够选择一段字符输出,strcpy则不能。

2.模拟代码

#include<stdio.h>
#include<string.h>
#include<assert.h>

char *mystrncpy(char *dest, const char *src,int n){
	assert((dest != NULL) && (src != NULL));//断言
	char *tmp = dest;//保存dest的起始地址,用于返回
	for (int i = 0; i < n; i++){
		*dest = *src;
		dest++;
		src++;
	}
	*dest = '\0';
	return tmp;
}

void main(){
	char dest[100] = { 0 };
	char src[] = "fghfafig";
	printf("%s\n", mystrncpy(dest,src,5));
	printf("%s\n", strncpy(dest,src,5));
}

3.对比截图

四.strcmp函数

1.函数简介

字符串逐字符比较大小。

原型声明strcmp(const char *s1,const char * s2);

头文件:#include <string.h> 和 #include <stdio.h>。

功能:strcmp函数是string compare(字符串比较)的缩写,用于比较两个字符串并根据比较结果返回整数。

基本形式为strcmp(str1,str2),若str1=str2,则返回零;若str1<str2,则返回负数;若str1>str2,则返回正数。

说明:这里面只能比较字符串,即可用于比较两个字符串常量,或比较数组和字符串常量,不能比较数字等其他形式的参数。

2.模拟代码

#include<stdio.h>
#include<string.h>
#include<assert.h>

int mystrcmp(const char *s1, const char *s2){
	assert((s1 != NULL) && (s2 != NULL));//断言
	int ret = 0;
	while (*s1 != '\0' || *s2 != '\0')//只需任一字符串未到结尾
	{
		ret = *s1 - *s2;
		if (ret != 0){
			break;
		}
		s1++;
		s2++;
	}

	return ret;
}

void main(){
	char s1[] = "abcde";
	char s2[] = "fghijk";
	printf("%d\n", mystrcmp(s1,s2));
	printf("%d\n", strcmp(s1,s2));
}

3.对比截图 

五.strcat函数

1.函数简介

将两个字符串进行连接。

原型声明extern char *strcat(char *dest, const char *src);

头文件:#include <string.h> 和 #include <stdio.h>。

功能:把src所指向的字符串(包括“\0”)复制到dest所指向的字符串后面(删除*dest原来末尾的“\0”)。要保证*dest足够长,以容纳被复制进来的*src。*src中原有的字符不变。返回指向dest的指针

说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。

2.模拟代码

#include<stdio.h>
#include<string.h>
#include<assert.h>

char *mystrcat(char *dest, const char *src){
	assert((dest != NULL) && (src != NULL));//断言
	char *tmp = dest;//保存dest的起始地址,用于返回
	while(*dest != '\0'){//到dest的末尾
		dest++;
	}
	while (*src != '\0'){//从src的起始接到dest的末尾
		*dest = *src;
		dest++;
		src++;
	}
	*dest = '\0';
	return tmp;
}

void main(){
	char dest[20] = "abcde";
	char src[] = "fghijk";
	printf("%s\n", mystrcat(dest,src));
	//printf("%s\n", strcat(dest,src));//和标准的对比
}

3.对比截图 

(1).自定义的mystrcat函数

(2).标准库中strcat函数 

六.strncat函数

1.函数简介

原型声明char * strncat(char *dest, const char *src, size_t n);

头文件:#include <string.h> 和 #include <stdio.h>。

功能:把src所指字符串的前n个字符添加到dest所指字符串的结尾处,并覆盖dest所指字符串结尾的'\0',从而实现字符串的连接。

说明:src和dest所指内存区域不可以重叠,并且dest必须有足够的空间来容纳src的字符串。

2.模拟代码

#include<stdio.h>
#include<string.h>
#include<assert.h>

char *mystrncat(char *dest, const char *src,int n){
	assert((dest != NULL) && (src != NULL));//断言
	char *tmp = dest;//保存dest的起始地址,用于返回
	while (*dest != '\0'){//到dest的末尾
		dest++;
	}
	for (int i = 0; i < n; i++){
		*dest = *src;
		dest++;
		src++;
	}
	*dest = '\0';
	return tmp;
}

void main(){
	char dest[100] = { 'a', 'b', 'c' };
	char src[] = "fg";
	printf("%s\n", mystrncat(dest,src,2));
	//printf("%s\n", strncat(dest,src,2));
}

3.对比截图

(1).自定义的mystrncat函数

(2).标准库中strncat函数

七.strstr函数

1.函数简介

strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串。如果是,则该函数返回 str1字符串从 str2第一次出现的位置开始到 str1结尾的字符串;否则,返回NULL。

原型声明string strstr( string1,string2);

头文件:#include <string.h> 和 #include <stdio.h>。

功能:strstr返回一个指针,指向string2在string1中首次出现的位置。

说明:寻找某字符串在另一字符串中第一次出现的位置,并返回查找到字符串的位置之后的全部字符串。 详细说明如下:

(1)参数是字符串类型的参数,要传入的是被查找的字符串。

(2)参数二是字符串类型的参数,传入的是要查找的字符串。

(3)strstr函数会寻找参数二在参数中出现的位置,并返回查找到字符串的位置之后的全部字符串。当没有查找到符合的字符串时,strstr函数会返回 FALSE(布尔值)。

(4)注意: strstr函数在查找时,大小写会被认为是不同的字符串。PHP另外提供一个大小写会被视为相同的函数: stristr。

(5)注意:如果只是要査找某字符串是否存在于另一字符串中,则建议使用 strpos这个函数, strpos函数执行的速度会比 strstr快,而且使用更少的内存

2.模拟代码

#include<stdio.h>
#include<string.h>
#include<assert.h>

char *mystrstr(char *s1, char *s2){
	assert((s1 != NULL) && (s2 != NULL));//断言
	char *tmp = NULL;
	int flag = 0;//标记上一个字符是否相同
	while (*s2!='\0'){
		if (*s1 != *s2){
			tmp = NULL;
			flag = 0;
		}
		if (*s1 == *s2){
			if (flag == 0){//上一个字符不同,记录起始位置
				tmp = s1;
			}
			flag = 1;//防止起始位置改变
			s2++;
		}
		s1++;
	}
	return tmp;
}

void main(){
	char s1[] = "abcdefghijk";
	char s2[] = "fgh";
	printf("%s\n", mystrstr(s1,s2));
	printf("%s\n", strstr(s1,s2));
}

3.对比截图 

4.注意

这种方法必须要把if (*s1 != *s2)的判断条件写在if (*s1 == *s2)之前。因为如果*s1==*s2,其中s2++,这时会继续满足判断 if (*s1 != *s2)的条件,从而产生错误结果。

八.atoi函数

1.函数简介

原型声明int atoi(const char *nptr);

头文件#include <stdlib.h> 和 #include <stdio.h>。

功能:扫描参数 nptr字符串,会跳过前面的空白字符(例如空格,tab缩进)等。如果 nptr不能转换成 int 或者 nptr为空字符串,那么将返回 0。

说明:该函数要求被转换的字符串是按十进制数理解的。atoi输入的字符串对应数字存在大小限制(与int类型大小有关),若其过大可能报错-1。

2.模拟代码

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<limits.h> //使用 INT_MAX、INT_MIN 判断是否超出整形范围

int myatoi(const char *nptr){
	assert(nptr != NULL);
	if (*nptr == '\0'){//如果字符串长度为0
		return 0;
	}
	while (*nptr == ' '){//如果字符串前面有很多空格
		nptr++;
	}
	int flag = 1;
	if (*nptr == '-'){//判断是正数还是负数
		flag = -1;
		nptr++;
	}
	int n = 0;
	while (*nptr != '\0'){
		if ((*nptr <= '0') || (*nptr >= '9')){//判断是否为十进制数字符,也可以用isdigit函数判断
			break;//不是 退出循环
		}
		n = n * 10 + flag*((int)*nptr - '0');
		if (n < INT_MIN || n>INT_MAX){//超出整形范围
			return -1;
		}
		nptr++;
	}

	return (int)n;
}

void main(){
	char str[] = "   -1426a432";
	printf("%d\n", myatoi(str));
	printf("%d\n", atoi(str));
}

3.对比截图

 

4.注意

注意该函数的一些特殊情况和如何将字符串转换为数字的方法。

 如有建议或想法,欢迎一起讨论学习~

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值