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

11、C 语言字符串函数总结

字符串函数的功能、参数、返回值、注意事项及示例等方面

C 语言字符串函数核心知识点总结

一、字符查找函数(strchr 与 strrchr)

1. 功能与原型

  • strchr:从左往右在字符串中查找指定字符,返回首个匹配字符的指针。

原型:char *strchr(const char *s, int c);

  • strrchr:从右往左在字符串中查找指定字符,返回首个匹配字符的指针。

原型:char *strrchr(const char *s, int c);

2. 参数与返回值

  • 参数
    • s:待查找的字符串(const修饰,不可修改)。
    • c:待查找的字符(以int类型传入,实际按char处理)。
  • 返回值
    • 成功:指向匹配字符的指针(可继续访问后续字符)。
    • 失败:NULL(未找到字符)。

3. 关键特性

  • 字符串结束符'\0'被视为字符串的一部分,可作为查找目标。
  • strchrstrrchr的区别仅在于查找方向,其余行为一致。

4. 示例代码

#include <string.h>

#include <stdio.h>

int main() {

    const char *s = "shijienameda";

    char *p1 = strchr(s, 'i');    // 从左找'i',返回指向首个'i'的指针

    char *p2 = strrchr(s, 'i');   // 从右找'i',返回指向最后一个'i'的指针

    printf("strchr: %s\n", p1);  // 输出 "ijienameda"

    printf("strrchr: %s\n", p2); // 输出 "ieda"

    return 0;

}

二、子串查找函数(strstr)

1. 功能与原型

  • 功能:在一个字符串(主串)中查找另一个字符串(子串)的首次出现位置。
  • 原型char *strstr(const char *haystack, const char *needle);

2. 参数与返回值

  • 参数
    • haystack:主串(被查找的字符串)。
    • needle:子串(待查找的字符串)。
  • 返回值
    • 成功:指向主串中子串起始位置的指针。
    • 失败:NULL(子串不存在于主串中)。

3. 关键特性

  • 查找时区分字符大小写(如"ABC""abc"视为不同子串)。
  • 若子串为空(needle[0] == '\0'),返回主串的起始地址。

4. 示例代码

#include <string.h>

#include <stdio.h>

int main() {

    const char *main_str = "chuangqianmingyueguang,yishidishangshuang";

    const char *sub_str = "yishi";

    char *p = strstr(main_str, sub_str);

    if (p != NULL) {

        printf("找到子串:%s\n", p);  // 输出 "yishidishangshuang"

    } else {

        printf("未找到子串\n");

    }

    return 0;

}

三、字符串长度函数(strlen)

1. 功能与原型

  • 功能:计算字符串的长度(不包含结束符'\0')。
  • 原型size_t strlen(const char *s);

2. 参数与返回值

  • 参数s:待计算长度的字符串。
  • 返回值size_t类型(无符号整数),表示字符串中字符的个数(不含'\0')。

3. 关键特性

  • '\0'作为长度计算的终止标志,若字符串无'\0',会导致越界访问(未定义行为)。
  • 返回值为size_t(无符号),与 signed 类型运算时需注意溢出(如strlen(s1) - strlen(s2)可能为负但显示为大正数)。

4. 示例代码

#include <string.h>

#include <stdio.h>

int main() {

    const char *s = "moranhuishou";

    size_t len = strlen(s);

    printf("字符串长度:%lu\n", len);  // 输出 13(不含'\0')

    return 0;

}

四、字符串复制函数(strcpy 与 strncpy)

1. 功能与原型

  • strcpy:将源字符串复制到目标内存,无长度限制。

原型:char *strcpy(char *dest, const char *src);

  • strncpy:将源字符串的前n个字符复制到目标内存,有长度限制。

原型:char *strncpy(char *dest, const char *src, size_t n);

2. 参数与返回值

  • 参数
    • dest:目标内存(可修改,需足够大以容纳复制内容)。
    • src:源字符串(const修饰,不可修改)。
    • nstrncpy专属,指定最大复制字符数。
  • 返回值:指向dest的指针(方便链式操作)。

3. 关键特性

  • strcpy
    • 自动复制源字符串的'\0'到目标内存。
    • 无边界检查,若src长于dest,会导致缓冲区溢出(危险!)。
  • strncpy
    • 最多复制n个字符,若src长度小于n,剩余位置用'\0'填充。
    • src长度大于等于n,不会自动添加'\0',需手动补充(否则目标字符串无终止符)。

4. 示例代码

#include <string.h>

#include <stdio.h>

int main() {

    char dest1[20] = {0};

    char dest2[20] = {0};

    const char *src = "shijienameda";

    

    // strcpy:复制整个字符串(含'\0')

    strcpy(dest1, src);

    printf("strcpy: %s\n", dest1);  // 输出 "shijienameda"

    

    // strncpy:复制前6个字符

    strncpy(dest2, src, 6);

    dest2[6] = '\0';  // 手动添加终止符(避免未定义行为)

    printf("strncpy: %s\n", dest2);  // 输出 "shijie"

    return 0;

}

五、字符串比较函数(strcmp 与 strncmp)

1. 功能与原型

  • strcmp:比较两个字符串的大小(按 ASCII 码值逐字符比较)。

原型:int strcmp(const char *s1, const char *s2);

  • strncmp:比较两个字符串的前n个字符。

原型:int strncmp(const char *s1, const char *s2, size_t n);

2. 参数与返回值

  • 参数
    • s1s2:待比较的两个字符串。
    • nstrncmp专属,指定比较的最大字符数。
  • 返回值
    • 正数:s1大于s2(首个不同字符的 ASCII 码差值)。
    • 0:s1s2相等。
    • 负数:s1小于s2

3. 关键特性

  • 比较规则:从左到右逐字符比较,直至遇到'\0'或不同字符为止。
  • strncmp仅比较前n个字符,若前n个字符均相同,返回 0(即使字符串后续不同)。

4. 示例代码

#include <string.h>

#include <stdio.h>

int main() {

    const char *s1 = "fhq9127";

    const char *s2 = "fhq9128";

    

    // strcmp:比较整个字符串

    int ret1 = strcmp(s1, s2);

    printf("strcmp: %d\n", ret1);  // 输出 -1(s1 < s2)

    

    // strncmp:比较前5个字符

    int ret2 = strncmp(s1, s2, 5);

    printf("strncmp: %d\n", ret2);  // 输出 0(前5个字符相同)

    return 0;

}

六、字符串拼接函数(strcat 与 strncat)

1. 功能与原型

  • strcat:将源字符串拼接到目标字符串的末尾。

原型:char *strcat(char *dest, const char *src);

  • strncat:将源字符串的前n个字符拼接到目标字符串的末尾。

原型:char *strncat(char *dest, const char *src, size_t n);

2. 参数与返回值

  • 参数
    • dest:目标字符串(可修改,需足够大以容纳拼接结果)。
    • src:源字符串(const修饰,不可修改)。
    • nstrncat专属,指定最大拼接字符数。
  • 返回值:指向dest的指针。

3. 关键特性

  • strcat
    • 自动覆盖dest的终止符'\0',并在拼接后添加新的'\0'
    • 无边界检查,若dest容量不足,会导致溢出。
  • strncat
    • 最多拼接n个字符,自动添加'\0'(即使拼接满n个字符)。
    • src长度小于n,仅拼接src的全部字符(含'\0')。

4. 示例代码

#include <string.h>

#include <stdio.h>

int main() {

    char dest[20] = "qingge";

    const char *src = ",nihaoshuai";

    

    // strcat:拼接整个字符串

    strcat(dest, src);

    printf("strcat: %s\n", dest);  // 输出 "qingge,nihaoshuai"

    

    // strncat:拼接前5个字符

    strncat(dest, "!", 5);

    printf("strncat: %s\n", dest);  // 输出 "qingge,nihaoshuai!"

    return 0;

}

七、字符串分割函数(strtok)

1. 功能与原型

  • 功能:按指定分隔符将字符串拆分为多个子串(令牌)。
  • 原型char *strtok(char *str, const char *delim);

2. 参数与返回值

  • 参数
    • str:首次调用时为待分割的字符串(可修改),后续调用为NULL(表示继续分割上一次的字符串)。
    • delim:分隔符集合(包含多个可能的分隔符,如" ,!"表示空格、逗号、感叹号均为分隔符)。
  • 返回值
    • 成功:指向当前子串的指针。
    • 失败:NULL(分割完毕)。

3. 关键特性

  • 修改原字符串:将分隔符替换为'\0',因此str必须指向可修改的内存(如栈数组),不可为字符串常量。
  • 状态保持:内部使用静态变量记录上次分割位置,线程不安全(多线程需用strtok_r)。

4. 示例代码

#include <string.h>

#include <stdio.h>

int main() {

    char str[] = "wo,ben lai yao!xingzou jianghu";

    char *token = strtok(str, " ,!");  // 首次调用,传入字符串

    while (token != NULL) {

        printf("子串:%s\n", token);

        token = strtok(NULL, " ,!");  // 后续调用,传入NULL

    }

    // 输出:

    // 子串:wo

    // 子串:ben

    // 子串:lai

    // ...(其余子串)

    return 0;

}

八、总结与注意事项

  1. 头文件:所有字符串函数均需包含 <string.h>
  2. 安全性
    • 无长度限制的函数(strcpystrcatstrcmp)可能导致缓冲区溢出,建议优先使用带n的版本(strncpystrncatstrncmp)。
    • strtok会修改原字符串,使用时需确保字符串可写(非const)。
  1. 终止符'\0':所有函数均依赖'\0'判断字符串结束,处理无终止符的字符数组时需格外小心。
  2. 返回值检查:对返回指针的函数(如strchrstrstr),使用前需判断是否为NULL,避免空指针访问。

我觉得掌握这些字符串函数的特性与用法,能高效处理字符串操作,是 C 语言编程的基础技能。实际开发中,需根据场景选择合适的函数,并始终注意边界检查与内存安全。

http://www.lryc.cn/news/620772.html

相关文章:

  • OpenCV 高斯模糊降噪
  • npm删除包
  • PyCharm性能优化与大型项目管理指南
  • C++:浅尝gdb
  • YouBallin正式上线:用Web3重塑创作者经济
  • 一种适用于 3D 低剂量和少视角心脏单光子发射计算机断层成像(SPECT)的可泛化扩散框架|文献速递-深度学习人工智能医疗图像
  • HTML <link rel=“preload“>:提前加载关键资源的性能优化利器
  • 【AAAI2025】计算机视觉|即插即用|FSTA:炸裂!这个即插即用模块,让你的SNN性能起飞!
  • DeepSeek补全IBM MQ 9.4 REST API 执行命令的PPT
  • 爬虫数据存储全攻略:从 Robots 协议到文件存储
  • 【深度学习新浪潮】VGGT待提升点分析及解决方案的思考
  • 基于大语言模型的爬虫数据清洗与结构化
  • pdf文件流或者本地文件读取
  • 掌握MATLAB三维可视化:从基础到实战技巧
  • OpenCV Canny 边缘检测
  • 【js】让项目支持倾听和朗读AI技术
  • OpenCV图像平滑处理方法详解
  • tp5集成elasticsearch笔记
  • 开疆智能Ethernet转ModbusTCP网关连接UR机器人配置案例
  • ComfyUI工作流不动了?
  • OpenCV 形态学操作
  • Spring AI PagePdfDocumentReader 全解析:基于 Apache PdfBox 的按页 PDF 读取实战
  • COLMAP进行密集重建,三维重建的步骤
  • [机器学习]08-基于逻辑回归模型的鸢尾花数据集分类
  • AUTOSAR汽车电子嵌入式编程精讲300篇-【自动驾驶】硬件在环(HIL)(二)
  • 第四天~在CANFD或CAN2.0的ARXML文件中实现Multiplexor多路复用信号实战
  • 依托AR远程协助,沟通协作,高效流畅
  • 读From GPT-2 to gpt-oss: Analyzing the Architectural Advances
  • 第四天-创建一个Classic CAN(经典CAN2.0)/CANFD的系统描述ARXML文件
  • IDEA、Pycharm、DataGrip等激活破解冲突问题解决方案之一