字符串函数1——简单篇

  • strlen
  • strcpy
  • strcat
  • strcmp
  • strncpy
  • strncat
  • strncmp

写在前面:本文比较长,覆盖了c语言中较多的字符串函数,作者会先带各位了解标准库对函数的介绍,然后模拟实现相关功能。

strlen

求字符串长度

在这里插入图片描述

size_t表明返回一个无符号类型的数字,是因为考虑到length为非零整数
const 可以保护str指向的那块空间不被改变,因为我们只是去求字符串的长度,而不会去解引用改变内容

注意

看这样一段代码

#include<stdio.h>
#include <string.h>
int main(void)
{
	if (strlen("ab") - strlen("abc") > 0)
	{
		printf(">");
	}
	else
	{
		printf("<");
	}
	return 0;
}

打印结果为“>”
原因是strlen的返回值是无符号类型的,此处结果是应该一个负数,在内存中存的是补码,但和0比较的时候,由于是无符号类型,所以被解读为一个很大的数字,远远大于了0

模拟

方法1(计数器)

#include <stdio.h>
#include <assert.h>
int my_strlen(const char* p)
{
	assert(p);
	int ret = 0;
	while (*p++){
		ret++;
	}
	return ret;
}
int main(void)
{
	char* p = "string";
	printf("%d ", my_strlen(p));
	return 0;
}

方法2(递归)

//2.递归
int my_strlen(const char* p)
{
	if (*p)
		return 1 + my_strlen(++p);
	else
		return 0;
}

方法3(指针-指针)

这种方法和VS2022库函数文件里的写法一样,所以我们参考微软工程师的代码

size_t __cdecl strlen (
        const char * str
        )
{
        const char *eos = str;

        while( *eos++ ) ;

        return( eos - str - 1 );
}

strcpy

拷贝字符串

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int main(void)
{
	char* arr1 = "abcd";
	char arr2[20] = { 0 };
	strcpy(arr2, arr1);
	printf("%s", arr2);
	return 0;
}

注意

如你所见,

1.arr2是被拷贝的空间,要求可以改变,应该是数组,而对源字符串不作要求,可以是字符指针指向的字符串常量,也可以是数组。
2.拷贝字符串以源字符串中的‘\0’结束。

可验证:
在这里插入图片描述

3.作为合格的程序员,你得保证目标空间可以存下你要拷贝的东西。(不要写bug)

模拟

char* my_strcpy(char* dest, const char* src)
{
	assert(dest && src);
	char* p = dest;
	while (*dest++ = *src++);
	return p;
}
int main(void)
{
	char arr1[] = "abcdd";
	char arr2[20] = { 0 };
	my_strcpy(arr2, arr1);
	printf("%s", arr2);
	return 0;
}

strcat

字符串追加

在这里插入图片描述

这个函数对’\0’要求很大,目标字符串和源字符串都得有’\0’。
这里插入图片描述

模拟

char* my_strcat(char* dest, const char* src)
{
	assert(dest && src);
	char* p = dest;
	while (*dest) {
		dest++;
	}
	while (*dest++ = *src++);
	return p;
}

注意

不要拿这个函数给自己追加,因为会覆盖\0,不能结束追加。
在这里插入图片描述

strcmp

在这里插入图片描述

是他!就是他!

比较字符串大小
需要对返回值做一下说明:
在这里插入图片描述

比如“abcdef”和
"abu’,虽然前者比后者在长度上大得多,但比较字符串是对应位置依次比较,在‘u’和’c’处u> c,所以比较结束,前者小于后者,返回一个小于零的值

话不多说,直接模拟

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <assert.h>
int my_strcmp(const char* p1, const char* p2)
{
	assert(p1 && p2);
	while (*p1 == *p2)
	{
		p1++;
		p2++;
	}
	if (!*p1)
		return 0;
	else
		return *p1 - *p2;
}
int main(void)
{
	char* p = "tomota";
	char* q = "tomoto";
	if (my_strcmp(p, q) > 0)
		printf(">");
	else if (my_strcmp(p, q) < 0)
		printf("<");
	else
		printf("=");
	return 0;
}

strncpy

在这里插入图片描述

说明

正常使用

在这里插入图片描述

你非要写BUG

目标空间不够用,你非要拷?
在这里插入图片描述

小手一抖,一个BUG

既然不够,拿0来凑
在这里插入图片描述

strncat

追加时,覆盖0,自己补0

在这里插入图片描述

不够追加直接补个结束标志

在这里插入图片描述
这小子发现自己“追”不上,就给了0然后跑路了

strncmp

很简单,多的一个参数就是用来指定比较前“几”个字符
自己用着看

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值