C语言---字符串函数和内存函数的实现

 C/C++总述:Study C/C++-CSDN博客

目录

求字符串长度
strlen
长度不受限制的字符串函数
strcpy
strcat
strcmp
长度受限制的字符串函数介绍
strncpy
strncat
strncmp
字符串查找
strstr
strtok
内存操作函数
memcpy
memmove

一、strlen 

描述

C 库函数 size_t strlen(const char *str) 计算字符串 str 的长度,字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0' )

声明

下面是 strlen() 函数的声明。

size_t strlen(const char *str)

参数

  • str -- 要计算长度的字符串。

返回值

该函数返回字符串的长度。

模拟实现

size_t my_strlen(const char* str) 
{
    const char* start = str; //字符串的起始位置就是str
    const char* end = str;

    while (*end != '\0') //用来找到字符串的末尾处
    {  
        end++;
    }
    return end - start; //最后指针减指针得到了字符串的长度
}

二、strcpy

描述

C 库函数 char *strcpy(char *dest, const char *src) 把 src 所指向的字符串复制到 dest

需要注意的是如果目标数组 dest 不够大,而源字符串的长度又太长,可能会造成缓冲溢出的情况。(会将源字符串中的 '\0' 拷贝到目标空间).

声明

下面是 strcpy() 函数的声明。

char *strcpy(char *dest, const char *src)

参数

  • dest -- 指向用于存储复制内容的目标数组。
  • src -- 要复制的字符串。

返回值

该函数返回一个指向最终的目标字符串 dest 的指针。

模拟实现

char *my_strcpy(char *dest, const char*src)
{ 
     char *ret = dest;
     assert(dest != NULL);
     assert(src != NULL);
 
     while((*dest++ = *src++))
     {
         ;
     }
     return ret;
}

三、strcat

描述

C 库函数 char *strcat(char *dest, const char *src) 把 src 所指向的字符串追加到 dest 所指向的字符串的结尾。

声明

下面是 strcat() 函数的声明。

char *strcat(char *dest, const char *src)

参数

  • dest -- 指向目标数组,该数组包含了一个 C 字符串,且足够容纳追加后的字符串。
  • src -- 指向要追加的字符串,该字符串不会覆盖目标字符串。

返回值

该函数返回一个指向最终的目标字符串 dest 的指针。

模拟实现

char *my_strcat(char *dest, const char*src)
{
     char *ret = dest;
     assert(dest != NULL);
     assert(src != NULL);
     while(*dest)
     {
     dest++;
     }
     while((*dest++ = *src++))
     {
         ;
     }
     return ret;
}

 四、strcmp

描述

C 库函数 int strcmp(const char *str1, const char *str2) 把 str1 所指向的字符串和 str2 所指向的字符串进行比较。

声明

下面是 strcmp() 函数的声明。

int strcmp(const char *str1, const char *str2)

参数

  • str1 -- 要进行比较的第一个字符串。
  • str2 -- 要进行比较的第二个字符串。

返回值

该函数返回值如下:

  • 如果返回值小于 0,则表示 str1 小于 str2。
  • 如果返回值大于 0,则表示 str1 大于 str2。
  • 如果返回值等于 0,则表示 str1 等于 str2。

模拟实现 

int my_strcmp(const char *str1, const char *str2) 
{
    while (*str1 && (*str1 == *str2)) 
    {
        str1++;
        str2++;
    }
    return *(unsigned char*)str1 - *(unsigned char*)str2;
}

五、 strstr

描述

C 库函数 char *strstr(const char *haystack, const char *needle) 在字符串 haystack 中查找第一次出现字符串 needle 的位置,不包含终止符 '\0'。

声明

下面是 strstr() 函数的声明。

char *strstr(const char *haystack, const char *needle)

参数

  • haystack -- 要被检索的 C 字符串。
  • needle -- 在 haystack 字符串内要搜索的小字符串。

返回值

该函数返回在 haystack 中第一次出现 needle 字符串的位置,如果未找到则返回 null。

模拟实现

int my_strstr(const char* haystack, const char* needle) 
{
    if (!*needle) 
    {
        return 0;
    }
    if (!*haystack || strlen(needle) > strlen(haystack)) 
    {
        return -1;
    }

    int i, j;
    for (i = 0; i <= strlen(haystack) - strlen(needle); i++) 
    {
        for (j = 0; j < strlen(needle); j++) 
        {
            if (haystack[i+j] != needle[j]) 
            {
                break;
            }
        }
        if (j == strlen(needle)) 
        {
            return i;
        }
    }

    return -1;
}

六、strtok

 描述

C 库函数 char *strtok(char *str, const char *delim) 分解字符串 str 为一组字符串,delim 为分隔符。

声明

下面是 strtok() 函数的声明。

char *strtok(char *str, const char *delim)

参数

  • str -- 要被分解成一组小字符串的字符串。
  • delim -- 包含分隔符的 C 字符串。

返回值

该函数返回被分解的第一个子字符串,如果没有可检索的字符串,则返回一个空指针。

模拟实现 

char* my_strtok_sim(char* str, const char* delim) 
{
    static char* p = NULL;   // 保存上次分割的位置
    if (str != NULL) 
    {
        p = str;   // 如果是第一次调用,初始化p为str
    } else if (p == NULL) 
    {
        return NULL;   // 如果p为空,表示已经完成了所有的分割,返回NULL
    }

    // 跳过分隔符
    while (*p != '\0' && strchr(delim, *p) != NULL) 
    {
        p++;
    }

    if (*p == '\0') 
    {
        return NULL;   // 如果p指向字符串结尾,表示已经完成了所有的分割,返回NULL
    }

    char* start = p;   // 记录子字符串的起始位置
    while (*p != '\0' && strchr(delim, *p) == NULL) 
    {
        p++;
    }

    if (*p != '\0') 
    {
        *p = '\0';   // 将分隔符替换为字符串结尾符,以便于后续调用
        p++;
    }

    return start;   // 返回子字符串的起始位置
}

 七、memcpy

描述

C 库函数 void *memcpy(void *str1, const void *str2, size_t n) 从存储区 str2 复制 n 个字节到存储区 str1

声明

下面是 memcpy() 函数的声明。

void* memcpy(void* dest, const void* src, size_t n)

参数

  • dest -- 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。
  • src -- 指向要复制的数据源,类型强制转换为 void* 指针。
  • n -- 要被复制的字节数。

返回值

该函数返回一个指向目标存储区 dest 的指针。

模拟实现

void* my_memcpy(void* dest, const void* src, size_t n) 
{
    char* dest_ptr = (char*) dest;
    const char* src_ptr = (const char*) src;

    for (size_t i = 0; i < n; i++) 
    {
        dest_ptr[i] = src_ptr[i];
    }

    return dest;
}

八、memmove

描述

C 库函数 void *memmove(void *str1, const void *str2, size_t n) 从 str2 复制 n 个字符到 str1,但是在重叠内存块这方面,memmove() 是比 memcpy() 更安全的方法。如果目标区域和源区域有重叠的话,memmove() 能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,复制后源区域的内容会被更改。如果目标区域与源区域没有重叠,则和 memcpy() 函数功能相同。

声明

下面是 memmove() 函数的声明。

void* memmove(void* dest, const void* src, size_t num)

参数

  • dest -- 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。
  • src -- 指向要复制的数据源,类型强制转换为 void* 指针。
  • num -- 要被复制的字节数。

返回值

该函数返回一个指向目标存储区 dest 的指针。

模拟实现

void* my_memmove(void* dest, const void* src, size_t num)
{
	void* ret = dest;
	assert(dest && src);
	if (dest < src) 
	{
		while (num--) 
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dst + 1;
			src = (char*)src + 1;
		}
	}
	else 
	{
		while (num--) 
		{
			*((char*)dest + count) = *((char*)src + count);
		}
	}
	return(ret);
}

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

禊月初三

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值