模拟实现一些库函数(1)(下)

简介: 模拟实现一些库函数(1)(下)

strcmp

首先该函数是比较函数其中,str1和str2是要进行比较的字符串。函数返回一个整数值来表示比较结果,返回值的含义如下:

若返回值为 0,表示两个字符串相等;

若返回值小于 0,表示str1小于str2;

若返回值大于 0,表示str1大于str2。

我们先看效果

int main()
{
  char str1[] = "ABCD";
  char str2[] = "ABCD";
  char str3[] = "ABC";
  char str4[] = "ABCDF";
  int ret1 = strcmp(str1, str2);
  int ret2 = strcmp(str1, str3);
  int ret3 = strcmp(str1, str4);
  printf("%d\n", ret1);
  printf("%d\n", ret2);
  printf("%d\n", ret3);
  return 0;
}
• 1
• 2
• 3
• 4
• 5
• 6
• 7
• 8
• 9
• 10
• 11
• 12
• 13
• 14

了解了效果后,我们来开始模拟

int my_strcmp(const char* str1, const char* str2)
{
  int ret = 0;
  assert(str1 && str2);
  while (!(ret = *(unsigned char*)str1 - *(unsigned char*)str2) && *str2)
  {
    ++str1;
    ++str2;
  }
  if (ret < 0)
    return -1;
  else if (ret > 1)
    return 1;
  else
    return ret;
}
int main()
{
  char str1[] = "ABCD";
  char str2[] = "ABCD";
  char str3[] = "ABC";
  char str4[] = "ABCDF";
  int ret1 = my_strcmp(str1, str2);
  int ret2 = my_strcmp(str1, str3);
  int ret3 = my_strcmp(str1, str4);
  printf("%d\n", ret1);
  printf("%d\n", ret2);
  printf("%d\n", ret3);
  return 0;
}
• 1
• 2
• 3
• 4
• 5
• 6
• 7
• 8
• 9
• 10
• 11
• 12
• 13
• 14
• 15
• 16
• 17
• 18
• 19
• 20
• 21
• 22
• 23
• 24
• 25
• 26
• 27
• 28
• 29
• 30

我们知道了strcmp的返回值是str1和str2进行比较后得出的,所以函数类型就是int型,在这里只是比较,不希望原字符串有任何改变,所以我们都用const来修饰两个参数,之后我们进入while循环来比较,因为当两个字符串的当前字符相等且尚未到达字符串的结束符时,继续执行循环体,即逐个比较两个字符串的字符,直到出现不同的字符或其中一个字符串到达结束符为止。所以我们设置了这样的循环条件,之后逐个比较str1和str2。

长度受限制的字符串函数

strncpy

该函数和strcpy函数的区别在于多了一个拷贝字符个数限制的条件,由于效果仅在于拷贝个数的限制,所以我们不在看效果,直接开始模拟。

char* my_strncpy(char* str1, size_t size, const char* str2)
{
  char* ret = str1;
  assert(str1 && str2);
  int i = 0;
  while (i < size&&*str2)
  {
    *str1++ = *str2++;
    i++;
  }
  *str1 = '\0';
  return ret;
}
int main()
{
  char str1[] = "***************";
  char str2[] = "hello world!";
  int k = 0;
  printf("请输入拷贝字符个数:");
  scanf("%d", &k);
  my_strncpy(str1, k, str2);
  printf("%s", str1);
  return 0;
}

我们只需要多加一个size_t的参数,来限制拷贝个数即可,注意拷贝完成后,由于个数的限制没有到达结束,所以我们要令循环结束后的str指针也就是拷贝完成后的str指针所指向的内容是’\0’。

strncat

同样的这个函数也只是多了一个追加的个数限制条件。我们直接来模拟这个函数的实现。

char* my_strncat(char* str1, size_t size, const char* str2)
{
  char* ret = str1;
  assert(str1 && str2);
  int i = 0;
  while (*str1)
  {
    str1++;
  }
  while (i < size&&*str2)
  {
    *str1++ = *str2++;
    i++;
  }
  *str1 = '\0';
  return ret;
}
int main()
{
  char str1[20] = "ABCD";
  char str2[] = "EFGHIJKL";
  int k = 0;
  printf("请输入追加字符的个数:");
  scanf("%d", &k);
  my_strncat(str1, k, str2);
  printf("%s", str1);
  return 0;
}

同样的,我们在知道了strcat函数的模拟以及strncpy函数的模拟,仅需要添加一个限制追加字符个数,并且将追加循环完成后str1所指向的内容赋值为’\0’即可。 其他的地方基本和上面几个函数的实现相似。

strncmp

这个函数与strcmp的区别也是多了一个比较个数的限制条件。为了防止大家误会这个函数的效果,我们来看一下这个函数的具体效果,再来模拟实现。

#include <stdio.h>
#include <string.h>
int main() {
    char str1[] = "hello";
    char str2[] = "world";
    int result = strncmp(str1, str2, 3);
    if (result == 0) {
        printf("前 3 个字符相等\n");
    }
    else if (result < 0) {
        printf("str1 小于 str2\n");
    }
    else {
        printf("str1 大于 str2\n");
    }
    return 0;
}

接下来,我们来具体模拟一下该函数

#include <stdio.h>
#include <string.h>
int my_strncmp(const char* str1, const char* str2, size_t size)
{
    int ret = 0;
    assert(str1 && str2);
    int i = 0;
    while (i < size)
    {
        ret = *(unsigned char*)str1 - *(unsigned char*)str2;
        if (ret != 0)
        {
            return ret > 0 ? 1 : -1;
        }
        if (*str1 == '\0')
            break;
        ++str1;
        ++str2;
        i++;
    }
    return 0;
}
int main()
{
    char str1[] = "hello";
    char str2[] = "world";
    int k = 0;
    printf("请输入str1和str2字符比较个数:");
    scanf("%d", &k);
    int result = my_strncmp(str1, str2, k);
    if (result == 0) {
        printf("前 3 个字符相等\n");
    }
    else if (result < 0) {
        printf("str1 小于 str2\n");
    }
    else {
        printf("str1 大于 str2\n");
    }
    return 0;
}

首先也是多了一个限制比较个数的参数,但是有一点不同的是,由于比较完前k个字符,接下来的字符不一定是’\0’,所以我们的代码和实现strcmp有一点不同,一个一个字符来比较即可。

字符串查找函strstr

首先我们了解一下strstr函数的作用:

strstr 函数是C语言标准库 <string.h> 中提供的一个字符串处理函数,用于在一个字符串中查找指定子字符串的第一次出现位置。

函数原型如下:

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

strstr 函数接受两个参数:str1 是要搜索的字符串,str2 是要查找的子字符串。

函数返回一个指向 str1 中第一次出现 str2 的位置的指针。如果未找到子字符串,返回 NULL。

来看一下效果:

int main() {
    char str1[] = "Hello, World!";
    char str2[] = "World";
    char* result = my_strstr(str1, str2);
    if (result != NULL) {
        printf("'%s' 第一次出现在 '%s' 中的位置是:%ld\n", str2, str1, result - str1);
    }
    else {
        printf("'%s' 未在 '%s' 中找到\n", str2, str1);
    }
    return 0;
}

接下来我们来模拟实现一下。

#include <stdio.h>
// 自定义实现 strstr 函数
char* my_strstr(const char* str1, const char* str2) {
    assert(str1);
    // 如果 str2 为空字符串,则直接返回 str1
    if (*str2 == '\0') {
        return (char*)str1;
    }
    // 遍历 str1
    while (*str1 != '\0') {
        const char* p1 = str1;
        const char* p2 = str2;
        // 在 str1 中查找 str2
        while (*p1 == *p2 && *p1 != '\0') {
            p1++;
            p2++;
        }
        // 如果 p2 指向了 str2 的结尾,说明找到了 str2,返回位置
        if (*p2 == '\0') {
            return (char*)str1;
        }
        // 在 str1 中继续查找
        str1++;
    }
    // 没有找到 str2,返回 NULL
    return NULL;
}
int main() {
    char str1[] = "Hello, World!";
    char str2[] = "World";
    char* result = my_strstr(str1, str2);
    if (result != NULL) {
        printf("'%s' 第一次出现在 '%s' 中的位置是:%ld\n", str2, str1, result - str1);
    }
    else {
        printf("'%s' 未在 '%s' 中找到\n", str2, str1);
    }
    return 0;
}

首先,我们需要两个字符串数组参数,在str1中寻找str2,由于我们只是寻找,并不希望原字符串发生改变,所以我们在接受参数时用const来修饰一下,如果str2指向的是空指针那么我们直接返回str1,如果不是进入我们的代码中,遍历str1,我们把str1和str2赋给p1和p2,然后设置一个如果存在才能进入的循环,然后给一个if语句,如果p2解引用等于‘\0’,说明str2到了末尾,也就是找到了,我们返回这个时候的str1指针所指向的位置,之后在if语句外str1++,如果没有碰到str2就遍历str1,这样我们最后遍历完str1,就能知道str2是否存在于str1中了。

总结

相信大家能看出来模拟这些函数有很多地方都是很相似的,那么就分享到这里,各位看客老爷万福金安。

目录
相关文章
|
6月前
|
C语言
模拟实现C语言中经典库函数,字符相关的函数与内存相关的函数
模拟实现C语言中经典库函数,字符相关的函数与内存相关的函数
模拟实现C语言中经典库函数,字符相关的函数与内存相关的函数
|
6月前
|
C语言
C语言-----qsort函数的功能以及模拟实现
C语言-----qsort函数的功能以及模拟实现
55 1
|
6月前
|
存储 C语言
c语言进阶部分详解(详细解析字符串常用函数,并进行模拟实现(上))
c语言进阶部分详解(详细解析字符串常用函数,并进行模拟实现(上))
111 0
|
6月前
|
存储 安全 C语言
c语言进阶部分详解(详细解析字符串常用函数,并进行模拟实现(下))
c语言进阶部分详解(详细解析字符串常用函数,并进行模拟实现(下))
123 0
|
C语言
C语言常见库函数的模拟实现
C语言常见库函数的模拟实现
57 0
|
C语言
【进阶C语言】字符串与内存库函数认识与模拟实现(1)
size_t为无符号整形,接受他的返回值的变量类型也应该为size_t 函数参数就是字符指针类型。const为了修饰*str,防止原字符串的数据被修改。 需要包含的头文件为:#include&lt;string.h&gt;
56 0
|
1月前
|
C语言
初识C语言3——函数(以猜数字游戏为例)
初识C语言3——函数(以猜数字游戏为例)
65 0
|
6月前
|
C语言 存储
C语言—部分库函数的模拟实现
C语言—部分库函数的模拟实现
|
6月前
|
算法
库函数讲解及模拟实现库函数
库函数讲解及模拟实现库函数
23 0
|
存储 编译器 C语言
【进阶C语言】字符串与内存库函数认识与模拟实现(2)
size_t为无符号整形,接受他的返回值的变量类型也应该为size_t 函数参数就是字符指针类型。const为了修饰*str,防止原字符串的数据被修改。 需要包含的头文件为:#include&lt;string.h&gt;
76 0