当前位置 : 主页 > 编程语言 > c语言 >

C语言模拟实现库函数详解

来源:互联网 收集:自由互联 发布时间:2023-02-01
目录 前言 1.字符串函数 1.1字符串控制函数 1.1.1 strlen的模拟 1.1.2 str(n)cpy的模拟 1.1.3 str(n)cmp的模拟 1.1.4 str(n)cat的模拟 1.1.5 strstr的模拟 1.1.6 strtok的使用 1.1.7 strerror的使用 1.2 字符串分类函
目录
  • 前言
  • 1.字符串函数
    • 1.1字符串控制函数
      • 1.1.1 strlen的模拟
      • 1.1.2 str(n)cpy的模拟
      • 1.1.3 str(n)cmp的模拟
      • 1.1.4 str(n)cat的模拟
      • 1.1.5 strstr的模拟
      • 1.1.6 strtok的使用
      • 1.1.7 strerror的使用
    • 1.2 字符串分类函数和字符串转换函数

    前言

    库函数的模拟,看似多此一举,实则汲取精华。

    1.字符串函数

    1.1字符串控制函数

    1.1.1 strlen的模拟

    求字符串长度

    //--------------------------------------
    size_t strlen( const char *string );
    //--------------------------------------
    //返回值用 int / size_t 各有好处
    int MyStrlen(const char* str)
    {
    	assert(str);
    	int cnt = 0;
    	while (*str != '\0')
    	{
    		str++;
    		cnt++;
    	}
    	return cnt;
    }
    int main()
    {
    	char arr[] = "bacon";
    	printf("%d\n", MyStrlen(arr));
    	return 0;
    }

    1.1.2 str(n)cpy的模拟

    拷贝字符串

    //-------------------------------------
    char* strcpy(char* dest, const char* src)
    //-------------------------------------
    char* MyStrcpy(char* dest, const char* src)
    {
    	assert(dest && src);
    	char* ret = dest;
    	while (*dest++ = *src++);
    	return ret;
    }
    int main()
    {
    	char str1[30] = "Bacon";
    	char str2[] = " is your friend.";
    	MyStrcpy(str1 + 5, str2);
    	printf("%s\n", str1);
    	return 0;
    }
    //Bacon is your friend.
    //------------------------------------------------------------
    char* strcpy(char* dest, const char* src, size_t num)
    //---------------------------------------------------------------
    char* MyStrncpy(char* dest, const char* src, size_t num)
    {
    	assert(dest && src);
    	char* ret = dest;
    	while (num--)
    	{
    		*dest++ = *src++;
    	}
    	return ret;
    }
    int main()
    {
    	char str1[20] = { 0 };
    	char str2[] = "bacon";
    	printf("%s\n", MyStrncpy(str1, str2, 4));
    	return 0;
    }
    //baco

    Bacon is your friend.

    baco

    1.1.3 str(n)cmp的模拟

    逐个比较字符串中的字符

    //-----------------------------------------------
    int strcmp(const char* str1, const char* str2)
    //-----------------------------------------------
    int MyStrcmp(const char* str1, const char* str2)
    {
    	assert(str1 && str2);
    	while (*str1 != '\0' && *str2 != '\0' && *str1 == *str2)
    	{
    		str1++;
    		str2++;
    	}
    	if (*str1 == *str2)
    		return 0;
    	else if (*str1 > *str2)
    		return 1;
    	else
    		return -1;
    }
    int main()
    {
    	char str1[] = "abcdef";
    	char str2[] = "abcdfe";
    	printf("%d\n", MyStrcmp(str1, str2));
    	return 0;
    }
    //-1
    //-----------------------------------------------------
    int strncmp(const char* str1, const char* str2, size_t num)
    //---------------------------------------------------------
    int MyStrncmp(const char* str1, const char* str1, size_t num)
    {
    	assert(dest && src);
    	while (num--)
    	{
    		if (*str1!= *str2)
    		{
    			if (*str1> *str2)
    				return 1;
    			else
    				return -1;
    		}
    		str1++;
    		str2++;
    	}
    	return 0;
    }
    int main()
    {
    	char str1[] = "abcdef";
    	char str2[] = "abcdfe";
    	printf("%d\n", MyStrncmp(str1, str2, 5));
    	return 0;
    }

    -1

    1.1.4 str(n)cat的模拟

    字符串追加

    //----------------------------------------------
    char* strcat(char* dest, const chat* src)
    //----------------------------------------------
    char* MyStrcat(char* dest, const char* src)
    {
    	assert(dest && src);
    	char* ret = dest;
    	//找到字符串结尾
    	while (*dest != '\0')
    	{
    		dest++;
    	}
    	while (*dest++ = *src++);
    	return ret;
    }
    int main()
    {
    	char str1[20] = "bacon";
    	char str2[] = " king";
    	printf("%s\n", MyStrcat(str1 , str2));
    	return 0;
    }
    //bacon king
    //----------------------------------------------------------
    char* strncat(char* dest, const char* src, size_t num);
    //----------------------------------------------------------
    char* MyStrncat(char* dest, const char* src, size_t num)
    {
    	assert(dest && src);
    	char* ret = dest;
    	while(*dest != '\0')
    	{
    		dest++;
    	}
    	while (num--)
    	{
    		*dest++ = *src++;
    	}
    	return ret;
    }
    int main()
    {
    	char str1[30] = "Bacon";
    	char str2[] = " is your friend";
    	printf("%s\n", MyStrncat(str1, str2, 8));
    	return 0;
    }
    //Bacon is your

    bacon king

    Bacon is your

    1.1.5 strstr的模拟

    查找子串

    //------------------------------------------------
    char* strstr(const char* str1, const char* str2)
    //--------------------------------------------------
    char* MyStrstr(const char* str1, const char* str2)
    {
    	assert(str1 && str2);
    	char* p = str1;
    	char* s1 = str1;
    	char* s2 = str2;
    	while (*p)//str1走完就可以跳出了
    	{
    		//找到可能匹配的位置
    		while (*s1 != *s2)
    		{
    			s1++;
    		}
    		p = s1;
    		while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2)
    		{
    			s1++;
    			s2++;
    		}
    		if (*s2 == '\0')
    		{
    			return p;
    		}
    		else
    		{
    			s1 = p + 1;
    			s2 = str2;
    			p = s1;
    		}
    	}
    	return NULL;
    }
    int main()
    {
    	char str1[] = "abbbcdef";
    	char str2[] = "bbc";
    	printf("%s\n", MyStrstr(str1, str2));
    	return 0;
    }

    1.1.6 strtok的使用

    切分字符串:根据给定的分隔符,把分隔符置 ‘\0’ ,并保存当前位置(存在静态区)

    传 非NULL : 从当前位置开始strtok传 NULL : 从上次保存的位置开始strtok

    比较奇怪的函数,此处仅示范使用方法

    //---------------------------------------------
    char* strtok(char* str , const char* sep)
    //---------------------------------------------
    //由函数定义:我们需要多次切分的时候——第一次传字符串地址,之后传NULL
    int main()
    {
    	char* p = "SiDiuPiDe233@icloud.com";
    	char sep[] = "@.";
    	char arr[30];
    	strcpy(arr, p);
    	char* i = NULL;
    	for (i = strtok(arr, sep); i != NULL; i = strtok(NULL, sep))
    	{
    		printf("%s\n", i);
    	}
    	return 0;
    }
    

    SiDiuPiDe
    icloud
    com

    1.1.7 strerror的使用

    打印错误码对应的信息

    在C语言中设置了一个 名为 “errno” 的全局变量,来保存错误码(不同运行错误的编号)

    //---------------------------------
    char* strerror(int errnum);
    //-----------------------------------
    int main()
    {
    	FILE* p = fopen("test.txt", "r");
    	if (NULL == p)
    		printf("%s\n", strerror(errno));
    	return 0;
    }
    

    No such file or directory

    1.2 字符串分类函数和字符串转换函数

    函数说明iscntrl任何控制字符isspace空白字符:空格‘ ’,换页‘\f’,换行’\n’,回车‘\r’,制表符’\t’或者垂直制表符’\v’isdigit十进制数字 0~9isxdigit十六进制数字,包括所有十进制数字,小写字母a~f,大写字母A~Fislower小写字母a~zisupper大写字母A~Zisalpha字母a~z或A~Zisalnum字母或者数字,az,AZ,0~9ispunct标点符号,任何不属于数字或者字母的图形字符(可打印)isgraph任何图形字符isprint任何可打印字符,包括图形字符和空白字符

    如果他的参数符合下列条件就返回真

    汲取:

    指针使用前 assert

    用const保护不需要修改的数据

    对于while中的指针的加减需要留心 while(*dest1++)while(*dest2) { dest2++; }

    • dest1跳出循环后是野指针
    • dest2跳出循环后指向’\0’

    到此这篇关于C语言模拟实现库函数详解的文章就介绍到这了,更多相关C语言库函数内容请搜索自由互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持自由互联!

    上一篇:C语言数据结构之单链表操作详解
    下一篇:没有了
    网友评论