当前位置: 首页 > backend >正文

strcmp 与 strcpy 的深入解析

strcmp 与 strcpy 的深入解析

一、strcpy 函数的深层细节

  1. 内存覆盖风险

    • 当源字符串长度超过目标数组大小时,strcpy会继续复制,覆盖目标数组后面的内存空间,可能导致程序崩溃或安全漏洞

    • 示例(危险操作):

    char dest[5];          // 只能容纳4个字符加结束符char src[] = "Hello";  // 长度为5+1=6strcpy(dest, src);     // 缓冲区溢出!
  2. 自我复制问题

    • 当源字符串和目标字符串内存区域重叠时,strcpy可能产生不可预期的结果

    • 应使用memmove代替:memmove(dest, src, strlen(src)+1)

  3. 返回值的妙用

    • 返回dest指针便于链式操作:

    char buf[100];printf("Result: %s\n", strcpy(buf, "test"));  // 直接打印复制结果

二、strcmp 函数的深入理解

  1. 比较逻辑细节

    • 比较的是字符的 ASCII 码值,而非视觉上的字符大小

    • 示例:

    // 大写字母ASCII值小于小写字母printf("%d\n", strcmp("Apple", "apple"));  // 负数// 比较到第一个不同字符即停止printf("%d\n", strcmp("application", "app"));  // 正数,因第4个字符'i' > '\0'
  2. 返回值的具体数值

    • C 标准仅规定返回值的正负性,不规定具体数值

    • 实际实现中通常返回两个不同字符的 ASCII 码差值

    • 不要依赖具体数值,只判断其正负或零

  3. 空字符串比较

    printf("%d\n", strcmp("", ""));       // 0,相等printf("%d\n", strcmp("", "a"));      // 负数,空字符串小于任何非空字符串printf("%d\n", strcmp("a", ""));      // 正数

三、与字符数组的操作差异

  1. 字符串 vs 字符数组

    // 这是字符串(自动添加'\0')char str1[] = "hello";  // 这是普通字符数组(不是字符串,没有结束符)char arr1[] = {'h', 'e', 'l', 'l', 'o'};  ​// 对arr1使用strcpy/strcmp会导致未定义行为
  2. 手动实现简易版本

    • 简易 strcpy 实现:

    char *my_strcpy(char *dest, const char *src) {char *p = dest;while ((*p++ = *src++)) ;  // 复制直到遇到'\0'return dest;}
    • 简易 strcmp 实现:

    int my_strcmp(const char *s1, const char *s2) {while (*s1 && *s2 && *s1 == *s2) {s1++;s2++;}return *s1 - *s2;  // 返回ASCII码差值}

四、更安全的替代函数详解

  1. strncpy 的使用要点

    char dest[10];char src[] = "Hello, world!";​// 最多复制9个字符(留一个位置给'\0')strncpy(dest, src, 9);dest[9] = '\0';  // 手动添加结束符,因为strncpy可能不添加
    • 注意:如果源字符串长度超过 n,strncpy不会添加 '\0'

  2. strlcpy 与 strlcat(POSIX 标准,更安全)

    • 自动添加结束符,返回源字符串长度:

    size_t strlcpy(char *dest, const char *src, size_t size);
  3. strcmp 家族的安全函数

    • strncmp:限制比较的最大字符数

    // 只比较前3个字符
    printf("%d\n", strncmp("apple", "appletree", 3));  // 0
    • stricmp/strcasecmp:忽略大小写比较(非标准函数)

五、实际应用场景

  1. strcpy 的典型用途

    • 初始化字符串

    • 字符串赋值操作

    • 缓冲区数据转移

  2. strcmp 的典型用途

    • 字符串排序(作为排序函数的比较器)

    • 命令行参数解析

    • 字符串查找与匹配

http://www.xdnf.cn/news/16454.html

相关文章:

  • Day 24:元组与os模块
  • 基于Hadoop3.3.4+Flink1.17.0+FlinkCDC3.0.0+Iceberg1.5.0整合,实现数仓实时同步mysql数据
  • 基于springboot的在线购票系统/在线售票系统
  • C++ 中实现 `Task::WhenAll` 和 `Task::WhenAny` 的两种方案
  • Gradle#Plugin
  • Triton编译
  • JavaScript - 实现套索工具的demo
  • MySQL 8.0.42创建MGR集群
  • 深度学习(鱼书)day04--手写数字识别项目实战
  • OpenCL study - code03 rgb2gray
  • 通过硬编码函数地址并转换为函数指针来调用函数
  • 6.Pinia快速入门
  • Mitk教程案例项目编译
  • ROS2总结(二)
  • Flutter中 Provider 的基础用法超详细讲解(二)之ChangeNotifierProvider
  • ES6模块详解:核心语法与最佳实践
  • c++加载qml文件
  • 小架构step系列27:Hibernate提供的validator
  • Oracle EBS 库存期间关闭状态“已关闭未汇总”处理
  • [ The Missing Semester of Your CS Education ] 学习笔记 shell篇
  • net8.0一键创建支持(Kafka)
  • Redis6.0+安装教程(Linux)
  • CPA青少年编程能力等级测评试卷及答案 Python编程(三级)
  • 分表分库与分区表
  • 【第六节】方法与事件处理器
  • docker-desktop引擎启动失败报wsl --update
  • Day4.AndroidAudio初始化
  • 数独求解器与生成器(回溯算法实现)
  • 【ESP32】无法找到: “${env:IDF_PATH}/components/“的路径报错问题以及CMAKE构建不成功问题
  • JVM terminated. Exit code=1