解析与模拟常用字符串函数strcpy,strcat,strcmp,strstr(一)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: 解析与模拟常用字符串函数strcpy,strcat,strcmp,strstr(一)

今天也是去学习了一波字符串函数,想着也为了加深记忆,所以写一下这篇博客。既帮助了我也帮助了想学习字符串函数的各位。下面就开始今天的字符串函数的学习吧。


strcpy与strncpy

在 C 语言中, strcpy 函数用于将一个字符串复制到另一个字符串中,并返回目标字符串的指针。该函数的原型如下:

 

 

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


其中, dest 表示目标字符串的指针, src 表示源字符串的指针。 strcpy 函数会将源字符串的内容复制到目标字符串中,并在复制结束后返回目标字符串的指针。

以下是一个简单的 strcpy 函数的模拟实现:

 

 

#define _CRT_SECURE_NO_WARNINGS 1
#include<assert.h>
char* My_strcopy(char* dest,const char* src)
{                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
  char* ret = dest;
  assert(dest != NULL);
  assert(src!=NULL);
  while(*dest++ = *src++);
  return ret;
}


在这个模拟实现中,我们首先检查目标字符串和源字符串是否为空指针,如果为空指针则返回空指针。然后,我们使用一个循环将源字符串的内容逐个复制到目标字符串中。最后,返回目标字符串的指针。


需要注意的是,这个模拟实现只适用于源字符串和目标字符串的长度较小的情况。在实际使用中,建议使用标准库中的 strcpy 函数,以确保代码的可移植性和正确性。                                                                                                                                                                                                

这样可能又有人问那我不想全部复制过去,我只想赋值前n个字符串那怎么实现呢?其实在这个库函数也有人创造出来过了,它就是strncpy,它也就比strcpy多一个n。下面是其解析与模拟与解析:


strncpy 函数是 C 语言中的内置函数之一,相较于 strcpy 函数,它使用更加灵活,功能更加强大。strncpy 函数将字符串源的前  num  个字符复制到目标字符串中,返回目标字符串的指针。它的语法形式为:

 char *strncpy(char *destination, const char *source, size_t num) 

需要注意的是, strncpy 函数在复制字符串时,不会在目标字符串的末尾添加空字符  '\0' ,除非源字符串的长度小于  num 。如果源字符串的长度大于等于  num ,则会将源字符串的前  num  个字符复制到目标字符串中。如果源字符串的长度小于  num ,则会将源字符串的所有字符复制到目标字符串中,并在目标字符串的末尾添加  num  减源字符串长度个空字符  '\0' 。

下面是一个简单的  strncpy  函数的模拟实现:

 

 

char* My_strncpy(char* dest, const char* src, int num)
{
  char* tmp = dest;
  while (num && (*dest++ = *src++))
    num--;
  if (num)
    while (num--)
      *dest++ = '\0';
  return tmp;
}
int main()
{
  int num = 0;
  char arr1[10] = { '\0' };
  char arr2[10] = { '\0' };
  printf("input?the?dest:>\n");
  gets(arr1);
  printf("input?the?scr:>\n");
  gets(arr2);
  printf("input?the?copy?num:>");
  scanf("%d", &num);
  char* ret = My_strncpy(arr1, arr2, num);
  printf("%s\n", ret);
}

在这个示例中,我们定义了一个  my_strncpy  函数来模拟  strncpy  函数的行为。在  my_strncpy  函数中,我们使用一个  while  循环来复制源字符串的字符到目标字符串中,直到复制的字符数达到  num  或者遇到源字符串的结束字符  '\0' 。然后,如果  num  不为零,我们使用另一个  while  循环将目标字符串的剩余部分填充为空字符  '\0' 。最后,我们返回目标字符串的指针。

在  main  函数中,我们定义了两个长度为10的字符数组  arr1  和  arr2 ,并使用  gets  函数获取用户输入的字符串。然后,我们使用  scanf  函数获取要复制的字符数,并调用  my_strncpy  函数将源字符串的前  num  个字符复制到目标字符串中。最后,我们使用  printf  函数输出复制后的目标字符串。

strcat与strncat

strcat 函数和 strncat 函数都是 C 语言标准库中的字符串操作函数,用于字符串的拼接和拷贝,下面是对它们的解析与模拟实现:


1.  strcat 函数:

- 函数声明: char *strcat(char *strDestination, const char *strSource) 。

- 函数功能:将源字符串拼接到目标字符串的末尾,并返回拼接后的目标字符串的首地址。

- 注意事项:目标字符串的空间必须足够大,且以 \0 结尾,源字符串必须以 \0 结尾,拼接后的字符串末尾也会自动添加 \0 。

- 模拟实现:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
char * my_strcat(char * dest, const char * src)
{
  assert(dest);
  assert(src);
  char * ret = dest;
  while (*dest)
    dest++;
  while (*dest++ = *src++)
    ;
  return ret;
}
int main()
{
  char a[20] = "abcd";
  char b[5] = "efgh";
  my_strcat(a, b);
  printf("%s\n", a);
  system("pause");
  return 0;
}


2.  strncat 函数:

- 函数声明: char *strncat(char *strDestination, const char *strSource, size_t count) 。

- 函数功能:将源字符串的前 count 个字符拼接到目标字符串的末尾,并返回拼接后的目标字符串的首地址。

- 注意事项:目标字符串的空间必须足够大,且以 \0 结尾,源字符串必须以 \0 结尾, count 表示需要拼接的字符个数,如果 count 大于源字符串的长度,则拼接有效字符后,在目标字符串末尾添加 \0 ;如果 count 小于源字符串的长度,则拼接有效字符后,在目标字符串末尾添加 \0 。

- 模拟实现:

 

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
char* my_strncat(char* dest, const char* src, size_t count)
{
    assert(dest);
    assert(src);
    char* ret = dest;
    while (*dest)
        dest++;
    while (count--)
    {
        if (*src)
            *dest++ = *src++;
        else
            break;
    }
    *dest = '\0';
    return ret;
}
int main()
{
    char a[20] = "abc";
    char b[5] = "efgh";
    my_strncat(a, b, 3);
    printf("%s\n", a);
    system("pause");
    return 0;
}


 

当然,上述代码只是一种模拟实现,真正的 strcat 和 strncat 函数会对参数进行更严格的检查,并处理各种边界情况,以确保程序的稳定性和安全性。


strcmpy

strcmp 是一个用于比较字符串大小的函数,其函数原型为

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

该函数会将两个字符串中的字符一个一个比较直到一方比另一方大或者小,若直到 '\0' 都相等则会返回0。注意其返回值:

第一个大于第二个 返回大于0的数字
第一个等于第二个 返回等于0的数字
第一个小于第二个 返回小于0的数字


以下是一个 strcmp 函数的模拟实现:

 
// 模拟实现 
int My_strcmp(const char* str1, const char* str2)
{
  assert(str1 && str2);
  while (*str1 == *str2)
  {
    if (*str1 == '\0')
      return 0;
    str1++;
    str2++;
  }
  return (*str1 - *str2);
}
 
int main()
{
  int ret = 0;
  char str1[10] = "dijshdf";
  char str2[10] = "fuhdsud";
  ret=My_strcmp(str1, str2);
  printf("%d\n", ret);
  return 0;
}



代码解析:首先使用 const 对 str1 和 str2 进行修饰保护,并对 str1 与 str2 进行断言保护,然后使用循环并解引用 str1 和 str2 并判断其是否相等,如果相等则循环继续, str1++ 并且 str2++ 直到遇到 '\0' ,此时返回0;若发现 str1 与 str2 解引用后不相等则返回 *str1-*str2 。

strstr

strstr 函数的作用是在一个字符串(str1)中查找另一个字符串(str2)的首次出现位置,并返回该位置的指针。其函数原型为

char*strstr(char*str1, const char*str2)

以下是对该函数的解析与模拟实现:

 

1. 函数解析:

-  str1 :被查找的目标字符串。
-  str2 :要查找的子字符串。
- 返回值:若 str2 是 str1 的子串,则返回 str2 在 str1 中首次出现的地址;如果 str2 不是 str1 的子串,则返回 NULL 。

2. 模拟实现:

 

该函数返回子串在目标串中第一次出现的地址

char* My_strstr(const char* str1, const char* str2)
{
  assert(str1 && str2);
  const char* s1 = str1;
  const char* s2 = str2;
  const char* p = str1;
  while (*p)
  {
    s1 = p;
    s2 = str2;
    while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2)
    {
      s1++;
      s2++;
    }
    if (*s2 == '\0')
    {
      return (char*)p;
    }
    p++;
  }
  return NULL;
}
 
int main()
{
  
 
    char arr1[] = "hello橘子真甜~";
  char arr2[] = "hello橘子";
  char* ret = My_strstr(arr1, arr2);
  if (ret == NULL)
  {
    printf("子串不存在\n");
  }
  else 
  {
    printf("字串存在:%s\n", ret);
  }
 
  return 0;
}


 

在上述代码中,首先使用 const 对 str1 和 str2 进行修饰保护,并对 str1 与 str2 进行断言保护,然后使用循环并解引用 str1 和 str2 并判断其是否相等,如果相等则循环继续, str1++ 并且 str2++ 直到遇到 '\0' ,此时返回 p 的地址;若发现 str1 与 str2 解引用后不相等则返回 NULL 。

文章已到篇尾,请各位多多支持。
















































































目录
相关文章
|
1天前
|
存储 C语言 数据格式
解析spritf和sscanf与模拟常用字符串函数strchr,strtok(二)
解析spritf和sscanf与模拟常用字符串函数strchr,strtok(二)
8 0
|
5月前
|
C语言
字符函数和字符串函数解析及模拟实现
字符函数和字符串函数解析及模拟实现
64 0
|
5月前
|
存储 算法 安全
【C语言 函数解析】C语言中的strcpy函数原型解析
【C语言 函数解析】C语言中的strcpy函数原型解析
49 0
|
5月前
|
算法 C语言 C++
【C语言 函数解析】C语言中的strcmp函数解析以及原型实现
【C语言 函数解析】C语言中的strcmp函数解析以及原型实现
253 0
|
5月前
|
存储 算法 编译器
【C语言 函数解析】C语言中的strcat 函数解析以及原型实现
【C语言 函数解析】C语言中的strcat 函数解析以及原型实现
157 0
|
C语言 C++
C语言常见字符串函数解析(上)
C语言常见字符串函数解析(上)
|
2月前
|
监控 网络协议 Java
Tomcat源码解析】整体架构组成及核心组件
Tomcat,原名Catalina,是一款优雅轻盈的Web服务器,自4.x版本起扩展了JSP、EL等功能,超越了单纯的Servlet容器范畴。Servlet是Sun公司为Java编程Web应用制定的规范,Tomcat作为Servlet容器,负责构建Request与Response对象,并执行业务逻辑。
Tomcat源码解析】整体架构组成及核心组件
|
2月前
|
存储 NoSQL Redis
redis 6源码解析之 object
redis 6源码解析之 object
61 6
|
1月前
|
存储 缓存 Java
什么是线程池?从底层源码入手,深度解析线程池的工作原理
本文从底层源码入手,深度解析ThreadPoolExecutor底层源码,包括其核心字段、内部类和重要方法,另外对Executors工具类下的四种自带线程池源码进行解释。 阅读本文后,可以对线程池的工作原理、七大参数、生命周期、拒绝策略等内容拥有更深入的认识。
什么是线程池?从底层源码入手,深度解析线程池的工作原理
|
1月前
|
开发工具
Flutter-AnimatedWidget组件源码解析
Flutter-AnimatedWidget组件源码解析
153 60

推荐镜像

更多