C/C++字符函数和字符串函数模拟实现与详解————长度不受限制的字符串函数

简介: C/C++字符函数和字符串函数模拟实现与详解————长度不受限制的字符串函数

1.前言

       对于字符串这一部分我们想到的大部分是字符串的创建,const修饰字符串,指针指向字符串,字符指针,字符数组这些内容,实际上在C语言中有一些字符函数和字符串函数。C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在常量字符串 中或者 字符数组中。字符串常量 适用于那些对它不做修改的字符串函数。

2strlen函数

       对于strlen函数我们可以访问cplusplus网站cplusplus进行查阅,看一看strlen函数的参数是什么以及返回类型是什么样子的。

        我们看到strlen函数的返回类型是size_t类型也就是无符号整数,它的类型是const char*str也就是字符串的地址,说到这里你有没有想到我们前面的笔试题,为什么在参数放字符元素会报错误,就是因为这里应该放字符的地址,由于字符串是用ASCLL码进行储存,二进制转化为十六进制,整形提升,就会形成一个野指针,产生报错。这个函数是计算字符的个数遇到’\0'结束,不计算’\0';例如我们想要计算某个字符串的长度,代码如下:

#include<stdio.h>
#include <string.h>
int main()
{
  char arr[] = "abcdef";
  size_t sz = strlen(arr);
  printf("%d\n", sz);
  return 0;
}

运行结果如下:

我们可以模拟实现一个strlen函数代码如下:

#include<stdio.h>
int my_strlen(const char* str)
{
  const char* p = str;
  while (*p != '\0')
  {
    p++;
  }
  return p - str;
}
int main()
{
  char arr[] = "abcdef";
  int ret = my_strlen(arr);
  printf("%d", ret);
  return 0;
}

       在这里我们主要用到指针减指针来计算字符的个数,当然我们也可以通过计数器或递归来进行操作,在这里不进行详细讲解。

3.strcpy函数

       我们进入cplusplus网站进行查阅strcpy的参数

        我们可以看到strcpy函数的返回类型是char*参数是 char * destination, const char * source

第一个参数是想要修改的字符串的指针,第二个参数是想要得到的字符出的指针由于第二个参数不需要我们修改,难免会出现错误,用const进行修饰。特别注意我们需要保证源字符串的长度必须大于第二个字符串的长度,否则会造成栈溢出的问题,导致程序崩溃。例如我们可以写一个程序来感受一下此函数的功能,代码如下:

#include<stdio.h>
#include <string.h>
int main()
{
  char arr[] = "abcdef";
  char arr1[] = "aaa";
  strcpy(arr, arr1);
  printf("%s\n", arr);
  return 0;
}

运行结果如下:

我们对函数strcpy进行模拟,代码如下:

#include<stdio.h>
#include<assert.h>
void my_strcpy(char* str1, const char* str2)
{
  assert(str1 && str2);
  char* p = str1;
  while (*str2 != '\0')
  {
    *p = *str2;
    p++;
    str2++;
  }
}
int main()
{
  char arr[20] = { 'a','b','c'};
  const char arr2[] = "ba";
  my_strcpy(arr, arr2);
  printf("%s", arr);
}

       在这个函数中我们就是先记录字符串的首元素的地址,再定义指针进行赋值,直到‘\0’赋值完成,返回首元素的指针。

4.strcat函数

        我们进入cplusplus网站进行查阅strcat的参数

       此函数的返回类型是char*,参数是char * destination, const char * source,和strcpy函数一样它的第一个参数是想要修改的字符串的指针,第二个参数是想要得到的字符出的指针由于第二个参数不需要我们修改,难免会出现错误,用const进行修饰。我们想要进行字符串的连接,代码如下

#include<stdio.h>
#include <string.h>
int main()
{
  char arr[100] = { 'a','b'};
  char arr1[] = "aaa";
  strcat(arr, arr1);
  printf("%s\n", arr);
  return 0;
}

运行结果如下:

我们对strcat函数进行模拟,代码如下:

#include<stdio.h>
#include<assert.h>
void my_strcat(char* str1, const char* str2)
{
  assert(str1 && str2);
  char* p = str1;
  while (*p != '\0')
  {
    p++;
  }
  while (*str2 != '\0')
  {
    *p = *str2;
    p++;
    str2++;
  }
  *p = *str2;
}
int main()
{
  char arr[20] = { 'a','b','d','e','f' };
  const char arr2[] = "ghi";
  my_strcat(arr, arr2);
  printf("%s", arr);
  return 0;
}

       在这里我们就是需要一个指针记录字符串的位置,一个移动,直到出现’\0‘然进修修改,注意需要两个字符串的总长度小于第一个字符串的容量。

5.strcmp函数

       此函数的返回类型是int,由于是对两个字符串进行比较所以不需要对字符串进行修改,所以用const进行修饰。

       它的返回值是整形,如果第一个字符串大于第二个返回大于0的数,小于返回小于0的数,等于返回0,比较就是逐个进行比较从第一个开始,相同则后移比较不同则进行比较返回结果。例如代码:

#include<stdio.h>
#include <string.h>
int main()
{
  const char arr[] = "abcdefg";
  const char arr2[] = "abcdf";
  int ret = strcmp(arr, arr2);
  if (ret > 0)
  {
    printf(">");
  }
  else if (ret < 0)
  {
    printf("<");
  }
  else
  {
    printf("=");
  }
  return 0;
}

运行结果如下:

我们对strcmp进行模拟实现,代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
int my_strcmp(const char* str1, const char* str2)
{
  assert(str1&& str2);
  while (*str1 == *str2)
  {
    str1++;
    str2++;
  }
  return *str1 - *str2;
}
int main()
{
  const char arr[] = "abcdefg";
  const char arr2[] = "abcdf";
  int ret = my_strcmp(arr, arr2);
  if (ret > 0)
  {
    printf(">");
  }
  else if (ret < 0)
  {
    printf("<");
  }
  else
  {
    printf("=");
  }
  return 0;
}

和上面叙述的一样,先找到不同的字符,进行相减,然后判断。

今天的内容就结束了希望大家可以一键三连。

 

目录
相关文章
|
1天前
|
安全 C语言 C++
C/C++字符串函数
C/C++字符串函数
|
15天前
|
编译器 C++
【C++核心】函数的应用和提高详解
这篇文章详细讲解了C++函数的定义、调用、值传递、常见样式、声明、分文件编写以及函数提高的内容,包括函数默认参数、占位参数、重载等高级用法。
15 3
|
2月前
|
编译器 C++ 容器
【C++】String常见函数用法
【C++】String常见函数用法
20 1
|
2月前
|
C++
c++常见函数及技巧
C++编程中的一些常见函数和技巧,包括生成随机数的方法、制表技巧、获取数字的个位、十位、百位数的方法、字符串命名技巧、避免代码修改错误的技巧、暂停和等待用户信号的技巧、清屏命令、以及避免编译错误和逻辑错误的建议。
21 6
|
2月前
|
存储 C++
c++学习笔记05 函数
C++函数使用的详细学习笔记05,包括函数的基本格式、值传递、函数声明、以及如何在不同文件中组织函数代码的示例和技巧。
30 0
c++学习笔记05 函数
|
2月前
|
存储 C++
【C/C++学习笔记】string 类型的输入操作符和 getline 函数分别如何处理空白字符
【C/C++学习笔记】string 类型的输入操作符和 getline 函数分别如何处理空白字符
33 0
|
2月前
|
Dart 编译器 API
Dart ffi 使用问题之在C++线程中无法直接调用Dart函数的问题如何解决
Dart ffi 使用问题之在C++线程中无法直接调用Dart函数的问题如何解决
|
2月前
|
存储 算法 搜索推荐
【C++】类的默认成员函数
【C++】类的默认成员函数
|
2月前
|
JavaScript C++
【C++ visual studio】解决VS报错:error C2447: “{”: 缺少函数标题(是否是老式的形式表?)【亲测有效,无效捶我】
【C++ visual studio】解决VS报错:error C2447: “{”: 缺少函数标题(是否是老式的形式表?)【亲测有效,无效捶我】
|
3月前
|
Rust 编译器 测试技术
Rust与C++的区别及使用问题之Rust中函数参数传递的问题如何解决
Rust与C++的区别及使用问题之Rust中函数参数传递的问题如何解决