【C语言】字符串函数strcpy&&strcat&&strcmp&&strstr的使⽤和模拟实现2

简介: 【C语言】字符串函数strcpy&&strcat&&strcmp&&strstr的使⽤和模拟实现

【C语言】字符串函数strcpy&&strcat&&strcmp&&strstr的使⽤和模拟实现1:https://developer.aliyun.com/article/1474749

运行代码图:

🌠strcmp 的使⽤

strcmp用于比较两个字符串是否相等,也就是比较字符串大小的函数。

函数原型:

int strcmp(const char *str1, const char *str2);
str1和str2是要比较的两个字符串指针。

strcmp比较字符串的大小,不是按字符串的长度进行比较,而是逐个字符地比较两个字符串对应的每个字符的ASCII码值。(比较使用的是无符号字符值的ASCII码顺序。)

  • 返回值:
  • 如果str1和str2完全相等,返回0。


如果str1大于str2(按ASCII码顺序),返回一个大于0的数。


如果str1小于str2,返回一个小于0的数。


strcmp()函数是C标准库string.h头文件中的函数。


字符串比较结束条件是遇到字符串末尾'\0'字符或者第一个不匹配

  • 字符。
字符串"cat" 和 "dog" 的比较:
'c'的ASCII码是99, 'd'的ASCII码是100,所以"cat"小于"dog"

字符串"hello" 和 "hello world" 的比较: 
前6个字符都相等,但第7个字符' '的ASCII码小于'\0',所以"hello"小于"hello world"

例子:

#include <string.h>

int main()
{
  char str1[] = "ahbyb";
  char str2[] = "asyzx";  

  int result = strcmp(str1, str2);

  if(result == 0)
    printf("Strings are equal\n");
  else if(result > 0)  
    printf("str1 is greater than str2\n"); 
  else
    printf("str1 is less than str2\n");

  return 0;
}

结果:

str1 is less than str2
• 1

🌉strcmp 模拟实现

int my_strcmp(const char* s1, const char* s2)
{
  while (*s1 == *s2)
  {
    if (*s1 == '\0')
      return 0;
    s1++;
    s2++;
  }
  return *s1 - *s2;
    //if (*s1 > *s2)
  //  return 1;
  //else
  //  return -1;

}

使用while循环逐个比较s1s2每个字符是否相等如果字符相等,继续循环比较下一个字符, 如果遇到字符串结束符’\0’,表示两个字符串完全匹配,直接返回0,如果在循环中找到不匹配的字符,使用*s1 - *s2返回两个字符的ASCII码差值

🌠 strstr 的使⽤

strstr用来查找一个字符串在另一个字符串中首次出现的位置。

strstr函数的原型:

char* strstr(const char* str1, const char* str2);
- str1: 主字符串,要在其中查找子字符串
- str2: 子字符串,要查找的字符串

strstr函数可以用来在一个字符串中查找另一个字符串首次出现的位置,如果str2不存在于str1中,则返回NULL;如果str2存在于str1中,则返回第一个匹配位置的指针。

strstr的比较原理是:

  1. str1字符串的起始位置开始,与str2字符串进行字符匹配比较。
  2. 如果匹配失败(当前字符不同),则str1指针后移一位,继续匹配。
  3. 如果匹配成功(到达str2字符串结束符'\0'),则匹配成功,返回str1指针地址。
  4. 如果遍历完str1仍未匹配成功,则返回NULL

例如:

char* p = strstr("hello world","world");
// p指向"world"子字符串在"hello world"中的位置

这里用一个图来解释strstr函数的工作原理:

        +----------------------+
str1 => | h e l l o   w o r l d| 
        +----------------------+
              |
              V
        +-----------+
str2 => | w o r l d |
        +-----------+
              |
              V
         比较第一个字符'h'与'w',不匹配
              |
              V
       指针后移到下一个字符'e'
              |
              V
         比较'e'与'w',不匹配
              |
              V
       指针后移到下一个字符'l'
              |  
              V
         比较'l'与'w',不匹配
              |
              V
       指针后移,依次比较直到匹配成功
              |
              V
         当str1指针指向'w'时,与str2第一个字符'w'匹配
              |
              V
       开始匹配后续字符,全部匹配成功
              |
              V
       返回str1指针地址,指向子字符串在主字符串中的位置

结果:

cegtbaab
• 1

当然也可以用图展示:

strstrstr1起始位置开始,用str2str1进行字符匹配比较。如果不匹配就后移str1指针,匹配成功就返回str1当前位置指针,上图就是返回c的地址。通过这种逐个匹配的方式找到子字符串在主字符串中的第一个匹配位置。

🌉strstr 的模拟实现

char* my_strstr(const char* str1, const char* str2)
{
  const char* cur = str1;//用cur记录str1的位置
  const char* s1 = NULL;//使用assert检查str1和str2是否为非空指针。
  const char* s2 = NULL;

  assert(str1 && str2);
  if (*str2 == '\0')//检查str2是否为空字符串,如果为空直接返回str1。
  {
    return (char*)str1;
  }

  while (*cur)//使用cur指针遍历str1。
  { //每次遍历:
    s1 = cur;//将cur赋值给s1,将str2赋值给s2,用于后续匹配
    s2 = str2;//当然,第几次失败后,重新回溯,重新开始匹配
    while (*s1 && *s2 && *s1 == *s2)
    {
      s1++;//开始匹配s1和s2中的字符,同时递增s1和s2。
      s2++;
    }
    if (*s2 == '\0')如果s1和s2匹配到结尾('\0'),表示找到了子串,返回cur。
    {
      return (char*)cur;
    }
    cur++;匹配失败后,cur++继续下次匹配。
  }
  return NULL;遍历完str1没有找到匹配,返回NULL。
}

时间复杂度为O(MN),其中M和N分别为主串和子串的长度。

若老铁们有点蒙蒙的,可以结合下图来理解:


🚩总结

这次阿森和你一起学习4个C语言中常用的基本字符操作函数,当然这只是一部分,还有很多,但阿森会慢慢和你一起学习。感谢你的收看,如果文章有错误,可以指出,我不胜感激,让我们一起学习交流,如果文章可以给你一个小小帮助,可以给博主点一个小小的赞😘

06B82E40-9B7C-40D3-9B22-A88277B789D7.gif

相关文章
|
9月前
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
141 0
|
9月前
|
存储 安全 编译器
深入C语言库:字符与字符串函数模拟实现
深入C语言库:字符与字符串函数模拟实现
|
9月前
|
C语言
C语言常见字符函数和字符串函数精讲
C语言常见字符函数和字符串函数精讲
|
6月前
|
存储 算法 C语言
【C语言程序设计——函数】素数判定(头歌实践教学平台习题)【合集】
本内容介绍了编写一个判断素数的子函数的任务,涵盖循环控制与跳转语句、算术运算符(%)、以及素数的概念。任务要求在主函数中输入整数并输出是否为素数的信息。相关知识包括 `for` 和 `while` 循环、`break` 和 `continue` 语句、取余运算符 `%` 的使用及素数定义、分布规律和应用场景。编程要求根据提示补充代码,测试说明提供了输入输出示例,最后给出通关代码和测试结果。 任务核心:编写判断素数的子函数并在主函数中调用,涉及循环结构和条件判断。
305 23
|
5月前
|
人工智能 Java 程序员
一文彻底搞清楚C语言的函数
本文介绍C语言函数:函数是程序模块化的工具,由函数头和函数体组成,涵盖定义、调用、参数传递及声明等内容。值传递确保实参不受影响,函数声明增强代码可读性。君志所向,一往无前!
97 1
一文彻底搞清楚C语言的函数
|
6月前
|
算法 C语言
【C语言程序设计——函数】利用函数求解最大公约数和最小公倍数(头歌实践教学平台习题)【合集】
本文档介绍了如何编写两个子函数,分别求任意两个整数的最大公约数和最小公倍数。内容涵盖循环控制与跳转语句的使用、最大公约数的求法(包括辗转相除法和更相减损术),以及基于最大公约数求最小公倍数的方法。通过示例代码和测试说明,帮助读者理解和实现相关算法。最终提供了完整的通关代码及测试结果,确保编程任务的成功完成。
264 15
【C语言程序设计——函数】利用函数求解最大公约数和最小公倍数(头歌实践教学平台习题)【合集】
|
6月前
|
C语言
【C语言程序设计——函数】亲密数判定(头歌实践教学平台习题)【合集】
本文介绍了通过编程实现打印3000以内的全部亲密数的任务。主要内容包括: 1. **任务描述**:实现函数打印3000以内的全部亲密数。 2. **相关知识**: - 循环控制和跳转语句(for、while循环,break、continue语句)的使用。 - 亲密数的概念及历史背景。 - 判断亲密数的方法:计算数A的因子和存于B,再计算B的因子和存于sum,最后比较sum与A是否相等。 3. **编程要求**:根据提示在指定区域内补充代码。 4. **测试说明**:平台对代码进行测试,预期输出如220和284是一组亲密数。 5. **通关代码**:提供了完整的C语言代码实现
119 24
|
6月前
|
存储 C语言
【C语言程序设计——函数】递归求斐波那契数列的前n项(头歌实践教学平台习题)【合集】
本关任务是编写递归函数求斐波那契数列的前n项。主要内容包括: 1. **递归的概念**:递归是一种函数直接或间接调用自身的编程技巧,通过“俄罗斯套娃”的方式解决问题。 2. **边界条件的确定**:边界条件是递归停止的条件,确保递归不会无限进行。例如,计算阶乘时,当n为0或1时返回1。 3. **循环控制与跳转语句**:介绍`for`、`while`循环及`break`、`continue`语句的使用方法。 编程要求是在右侧编辑器Begin--End之间补充代码,测试输入分别为3和5,预期输出为斐波那契数列的前几项。通关代码已给出,需确保正确实现递归逻辑并处理好边界条件,以避免栈溢出或结果
304 16
|
6月前
|
存储 编译器 C语言
【C语言程序设计——函数】分数数列求和2(头歌实践教学平台习题)【合集】
函数首部:按照 C 语言语法,函数的定义首部表明这是一个自定义函数,函数名为fun,它接收一个整型参数n,用于指定要求阶乘的那个数,并且函数的返回值类型为float(在实际中如果阶乘结果数值较大,用float可能会有精度损失,也可以考虑使用double等更合适的数据类型,这里以float为例)。例如:// 函数体代码将放在这里函数体内部变量定义:在函数体中,首先需要定义一些变量来辅助完成阶乘的计算。比如需要定义一个变量(通常为float或double类型,这里假设用float。
163 3
|
6月前
|
存储 算法 安全
【C语言程序设计——函数】分数数列求和1(头歌实践教学平台习题)【合集】
if 语句是最基础的形式,当条件为真时执行其内部的语句块;switch 语句则适用于针对一个表达式的多个固定值进行判断,根据表达式的值与各个 case 后的常量值匹配情况,执行相应 case 分支下的语句,直到遇到 break 语句跳出 switch 结构,若没有匹配值则执行 default 分支(可选)。例如,在判断一个数是否大于 10 的场景中,条件表达式为 “num> 10”,这里的 “num” 是程序中的变量,通过比较其值与 10 的大小关系来确定条件的真假。常量的值必须是唯一的,且在同一个。
150 2