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

简介: 解析与模拟常用字符串函数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 。

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
















































































目录
相关文章
|
存储 C语言 数据格式
解析spritf和sscanf与模拟常用字符串函数strchr,strtok(二)
解析spritf和sscanf与模拟常用字符串函数strchr,strtok(二)
197 0
|
C语言
字符函数和字符串函数解析及模拟实现
字符函数和字符串函数解析及模拟实现
218 0
|
存储 算法 安全
【C语言 函数解析】C语言中的strcpy函数原型解析
【C语言 函数解析】C语言中的strcpy函数原型解析
511 0
|
算法 C语言 C++
【C语言 函数解析】C语言中的strcmp函数解析以及原型实现
【C语言 函数解析】C语言中的strcmp函数解析以及原型实现
1425 0
|
存储 算法 编译器
【C语言 函数解析】C语言中的strcat 函数解析以及原型实现
【C语言 函数解析】C语言中的strcat 函数解析以及原型实现
615 0
|
C语言 C++
C语言常见字符串函数解析(上)
C语言常见字符串函数解析(上)
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下 7 种: • 代理模式 • 适配器模式 • 装饰者模式 • 桥接模式 • 外观模式 • 组合模式 • 享元模式
870 140
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
1362 29
|
前端开发 数据安全/隐私保护 CDN
二次元聚合短视频解析去水印系统源码
二次元聚合短视频解析去水印系统源码
548 4
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

推荐镜像

更多
  • DNS