C语言精粹:深入探索字符串函数

大家好,这里是小编的博客频道
小编的博客:就爱学编程

很高兴在CSDN这个大家庭与大家相识,希望能在这里与大家共同进步,共同收获更好的自己!!!

本文目录

  • 引言
  • 正文
    • (1)常见字符串函数
      • 1. strlen - 计算字符串长度
      • 2. strcpy - 复制字符串
      • 3. strcat - 连接字符串
      • 4. strcmp - 比较字符串
    • (2)非常见字符串函数
      • 1. strstr()
      • 2. sscanf()
      • 3. strchr()
      • 4. strncat()
      • 5. strncmp()
      • 6.strtok 函数使用介绍
        • 函数原型
        • 返回值
        • 使用示例
        • 输出结果
        • 注意事项
  • 快乐的时光总是短暂,咱们下篇博文再见啦!!!不要忘了,给小编点点赞和收藏支持一下,在此非常感谢!!!

引言

在C语言中,字符串是以字符数组的形式表示的,并以空字符('\0')作为结束标志。标准库提供了一系列用于处理字符串的函数,这些函数定义在头文件 <string.h> 中。下面是一些常用的字符串函数及其模拟实现,一起来看看吧。

在这里插入图片描述


那接下来就让我们开始遨游在知识的海洋!

正文


在C语言中,字符串是以字符数组的形式表示的,并以空字符('\0')作为结束标志。标准库提供了一系列用于处理字符串的函数,这些函数定义在头文件 <string.h> 中。下面是一些常用的字符串函数及其模拟实现:

(1)常见字符串函数


1. strlen - 计算字符串长度

功能: 返回字符串的长度(不包括终止的空字符)。

原型: size_t strlen(const char *str);

模拟实现:

#include <stdio.h>size_t my_strlen(const char *str) {const char *s = str;while (*s != '\0') {++s;}return s - str;
}int main() {char str[] = "Hello, World!";printf("Length of '%s' is %zu
", str, my_strlen(str));return 0;
}

2. strcpy - 复制字符串

功能: 将源字符串复制到目标字符串中。

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

模拟实现:

#include <stdio.h>char* my_strcpy(char *dest, const char *src) {char *d = dest;while ((*d++ = *src++) != '\0');return dest;
}int main() {char src[] = "Hello, Copy!";char dest[50];  // 确保目标数组有足够的空间my_strcpy(dest, src);printf("Copied string: %s
", dest);return 0;
}

3. strcat - 连接字符串

功能: 将源字符串连接到目标字符串的末尾。

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

模拟实现:

#include <stdio.h>char* my_strcat(char *dest, const char *src) {char *d = dest;while (*d != '\0') {d++;}while ((*d++ = *src++) != '\0');return dest;
}int main() {char str1[50] = "Hello, ";char str2[] = "World!";my_strcat(str1, str2);printf("Concatenated string: %s
", str1);return 0;
}

4. strcmp - 比较字符串

功能: 按字典顺序比较两个字符串。

原型: int strcmp(const char *str1, const char *str2);

  • 如果返回值小于0,表示 str1 小于 str2
  • 如果返回值等于0,表示 str1 等于 str2
  • 如果返回值大于0,表示 str1 大于 str2

模拟实现:

#include <stdio.h>int my_strcmp(const char *str1, const char *str2) {while (*str1 && (*str1 == *str2)) {str1++;str2++;}return *(unsigned char *)str1 - *(unsigned char *)str2;
}int main() {char str1[] = "apple";char str2[] = "Apple";int result = my_strcmp(str1, str2);if (result < 0) {printf("%s is less than %s
", str1, str2);} else if (result > 0) {printf("%s is greater than %s
", str1, str2);} else {printf("%s is equal to %s
", str1, str2);}return 0;
}
  • 这些是C语言中最常用的一些字符串处理函数的简单实现示例。在实际开发中,建议使用标准库提供的函数,因为它们经过优化且更加可靠。不过,了解这些函数的内部工作原理有助于更好地理解字符串处理的细节和潜在问题。

在C语言中,字符串处理是一个常见的任务,而标准库提供了一系列函数来简化这些操作。尽管像strlenstrcmpstrcpy这样的函数广为人知且频繁使用,但还有一些不那么常见但仍然非常有用的字符串函数。以下是对一些不常见的C语言字符串函数的介绍和使用示例:

(2)非常见字符串函数

1. strstr()

功能:检索子串在字符串中首次出现的位置。

头文件<string.h>

用法char *strstr(char *str, char *substr);

  • str:要检索的字符串。
  • substr:要检索的子串。

返回值:返回字符串str中第一次出现子串substr的地址;如果没有找到子串,则返回NULL

示例

#include <stdio.h>
#include <string.h>int main() {char a[] = "abcdefg";char b[] = "bc";char *ret = strstr(a, b);if (ret == NULL) {printf("Can not find!
");} else {printf("%s
", ret); // 输出 bcdefg}return 0;
}

2. sscanf()

功能:从字符串读取格式化输入。

头文件<stdio.h>

用法int sscanf(const char *str, const char *format, ...);

  • str:输入的字符串。
  • format:格式字符串,指定后续参数的类型和如何解释输入字符串。

返回值:成功转换并赋值的项数;如果到达文件末尾或发生读错误,则返回一个负值。

示例

#include <stdio.h>int main() {char buf[512] = {0};sscanf("123456", "%s", buf);printf("%s
", buf); // 输出 123456return 0;
}

3. strchr()

功能:查找字符串中首次出现的字符。

头文件<string.h>

用法char *strchr(char *str, char ch);

  • str:要搜索的字符串。
  • ch:要查找的字符。

返回值:返回指向首次出现字符ch的位置的指针;如果未找到该字符,则返回NULL

示例

#include <stdio.h>
#include <string.h>int main() {char str[] = "Hello, World!";char ch = 'W';char *pos = strchr(str, ch);if (pos != NULL) {printf("Character '%c' found at position: %ld
", ch, pos - str);} else {printf("Character '%c' not found.
", ch);}return 0;
}

4. strncat()

功能:连接两个字符串,最多复制n个字符。

头文件<string.h>

用法char *strncat(char *dest, const char *src, size_t n);

  • dest:目标字符串。
  • src:源字符串。
  • n:要从src复制到dest的最大字符数。

返回值:返回目标字符串dest的指针。

注意事项:确保目标字符串有足够的空间来容纳连接后的结果。

示例

#include <stdio.h>
#include <string.h>int main() {char dest[20] = "Hello, ";char src[] = "World!!!";strncat(dest, src, 5); // 只连接前5个字符printf("%s
", dest); // 输出 Hello, Worldreturn 0;
}

5. strncmp()

功能:比较两个字符串的前n个字符。

头文件<string.h>

用法int strncmp(const char *s1, const char *s2, size_t n);

  • s1, s2:要比较的字符串。
  • n:要比较的字符数。

返回值:小于0表示s1小于s2;等于0表示两者相等(在前n个字符内);大于0表示s1大于s2

示例

#include <stdio.h>
#include <string.h>int main() {char str1[] = "Apple";char str2[] = "Banana";int result = strncmp(str1, str2, 4); // 比较前4个字符if (result < 0) {printf("str1 is less than str2 in the first 4 characters.
");} else if (result > 0) {printf("str1 is greater than str2 in the first 4 characters.
");} else {printf("The first 4 characters of str1 and str2 are equal.
");}return 0;
}

6.strtok 函数使用介绍

strtok 是 C 标准库中的一个字符串处理函数,用于将字符串分割成一系列的“标记”(tokens)。这个函数在处理和分析以特定分隔符(delimiter)分隔的字符串时非常有用。例如,解析 CSV 文件、命令行参数或任何需要按特定字符分割的文本数据。

函数原型
char *strtok(char *str, const char *delim);
char *strtok_r(char *str, const char *delim, char **saveptr); // 线程安全版本,POSIX标准
  • str: 要分割的字符串。首次调用时传入要处理的字符串;后续调用应传入 NULL 以继续从上次停止的地方开始分割。
  • delim: 包含所有用作分隔符的字符集合。
  • saveptr (仅在 strtok_r 中): 一个指向 char* 的指针,用于保存状态信息以便在多次调用之间保持连续性(线程安全)。
返回值
  • 成功时返回指向下一个标记的指针。
  • 没有更多标记可提取时返回 NULL。
使用示例

以下是一个简单的例子,演示如何使用 strtok 来分割一个包含逗号分隔值的字符串:

#include <stdio.h>
#include <string.h>int main() {char str[] = "apple,banana,cherry,date";const char delim[2] = ",";char *token;// 获取第一个标记token = strtok(str, delim);// 循环获取后续的标记,直到没有更多的标记为止while (token != NULL) {printf("Token: %s
", token);token = strtok(NULL, delim);  // 注意这里传入的是 NULL}return 0;
}
输出结果
Token: apple
Token: banana
Token: cherry
Token: date
注意事项
  1. 修改原字符串strtok 会修改传入的原始字符串,用空字符 ('\0') 替换分隔符。因此,如果需要保留原始字符串,应在调用 strtok 之前对其进行复制。
  1. 不可重入和线程安全性:标准的 strtok 不是线程安全的,因为它使用一个静态变量来存储上下文信息。在多线程环境中,应该使用 POSIX 提供的 strtok_r 函数,它接受一个额外的参数来保存状态信息,从而避免竞态条件。
  1. 连续调用:在第一次调用后,必须传递 NULL 作为 str 参数以继续分割操作。
  1. 空字符串的处理:如果 str 是一个空字符串,strtok 将立即返回 NULL 而不会修改 str
  1. 分隔符中的特殊字符:如果分隔符字符串中包含空字符,则行为未定义。通常应避免这种情况。

快乐的时光总是短暂,咱们下篇博文再见啦!!!不要忘了,给小编点点赞和收藏支持一下,在此非常感谢!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/7217.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信阅读网站小程序的设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

RabbitMQ 死信队列

文章目录 前言1、死信交换机 DLX 与死信队列 DLQ2、死信队列的实现2.1、声明原队列信息2.2、声明死信队列信息2.3、完整示例 3、死信消息流转原理 前言 消息过期以后&#xff0c;如果没有任何配置&#xff0c;是会直接丢弃的。我们可以通过配置让这样的消息变成死信&#xff0…

《边界感知的分而治之方法:基于扩散模型的无监督阴影去除解决方案》学习笔记

paper&#xff1a;Boundary-Aware Divide and Conquer: A Diffusion-Based Solution for Unsupervised Shadow Removal 目录 摘要 1、介绍 2、相关工作 2.1 阴影去除 2.2 去噪扩散概率模型&#xff08;Denoising Diffusion Probabilistic Models, DDPM&#xff09; 3、方…

leetcode28-找出字符串中第一个匹配的下标

leetcode 28 思路 首先循环haystack&#xff0c;然后当当前字符和needle的首字母相同的时候截取出长度等于needle的字符串&#xff0c;进行比较是否相等&#xff0c;如果相等则说明当前index为第一个匹配的下标&#xff0c;如果不相等则说明不正确继续进行遍历&#xff0c;直…

【esp32-uniapp】uniapp小程序篇02——引入组件库

一、引入组件库&#xff08;可自行选择其他组件库&#xff09; 接下来介绍colorUI、uview plus的安装&#xff0c;其他的安装可自行查找教程 1.colorUI weilanwl/coloruicss: 鲜亮的高饱和色彩&#xff0c;专注视觉的小程序组件库 下载之后解压&#xff0c;将\coloruicss-ma…

YOLOv8改进,YOLOv8检测头融合DynamicHead,并添加小目标检测层(四头检测),适合目标检测、分割等,全网独发

摘要 作者提出一种新的检测头,称为“动态头”,旨在将尺度感知、空间感知和任务感知统一在一起。如果我们将骨干网络的输出(即检测头的输入)视为一个三维张量,其维度为级别 空间 通道,这样的统一检测头可以看作是一个注意力学习问题,直观的解决方案是对该张量进行全自…

Vue2官网教程查漏补缺学习笔记 - 3Vue实例4模板语法5计算属性监听器

3 Vue实例 3.1 创建一个 Vue 实例 每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的&#xff1a; var vm new Vue({// 选项 })虽然没有完全遵循 MVVM 模型&#xff0c;但是 Vue 的设计也受到了它的启发。因此在文档中经常会使用 vm (ViewModel 的缩写) 这个变…

【高项】6.3 排列活动顺序 ITTO

输入 项目管理计划组件&#xff1a; ① 进度管理计划&#xff1b;② 范围基准 项目文件&#xff1a; ① 假设日志&#xff1b;② 活动属性&#xff1b;③ 活动清单&#xff1b;④ 里程碑清单 工具与技术 紧前关系绘图法&#xff08;PDM&#xff09; ① 完成到开始&…

将Deepseek接入本地Vscode

第一步&#xff1a;获取Deepseek APIKEY 1.1 登录Deepseek官网 https://www.deepseek.com/ 1.2 选择API开放平台 1.3 注册账号并登录 1.4 登录成功后的就界面 1.5 点击左侧菜单栏“API keys”&#xff0c;并创建API key 名称自定义输入 生成API key 复制保存&#xff0c;丢失…

docker使用笔记

文章目录 1.Docker 与容器2.核心概念与安装配置2.1 核心概念2.2 docker 安装ubuntu使用官方的脚本自动安装准备条件准备安装安装Docker安装Docker 命令补全工具允许非Root用户执行docker 命令最后一步 更新.bashrc文件 [修改docker 默认的存储路径](https://www.cnblogs.com/du…

vim如何设置制表符表示的空格数量

:set tabstop4 设置制表符表示的空格数量 制表符就是tab键&#xff0c;一般默认是四个空格的数量 示例&#xff1a; &#xff08;vim如何使设置制表符表示的空格数量永久生效&#xff1a;vim如何使相关设置永久生效-CSDN博客&#xff09;

PPT添加与管理批注的操作指南

​​​ 批注是PPT中一个非常实用的功能&#xff0c;它不仅能帮助我们在演讲和设计过程中记录想法&#xff0c;还能与他人协作时提供有价值的反馈。无论是团队讨论、审稿&#xff0c;还是个人思考&#xff0c;批注的运用都能让我们的PPT更加完善和高效。我会详细介绍如何在PPT中…

CASAIM与友达光电达成深度合作,CASAIM IS自动化蓝光测量技术为创新显示技术发展注入新的活力

近期&#xff0c;CASAIM与友达光电股份有限公司在液晶显示面板智能自动三维检测技术上达成深度合作&#xff0c;联合打造CASAIM IS全自动化智能检测系统,助力光电产品显示面板制造全自动化3d测量&#xff0c;实现高精度、高效率测量和检测&#xff0c;进一步提升产品质量和生产…

【已解决】OSS配置问题

OSS SDK快速入门_对象存储(OSS)-阿里云帮助中心 阿里官方的SDK使用方法还得配置环境变量access Key、access Secret &#xff0c;我没有配置&#xff0c;仅把access Key和access Secret写到了yml文件读取&#xff0c;结果上传图片时还是出现下面的问题。 [ ERROR ] [ com.s…

STM32 硬件I2C读写

单片机学习&#xff01; 目录 前言 一、步骤 二、配置I2C外设 2.1 开启I2C外设和GPIO口时钟 2.2 GPIO口初始化为复用开漏模式 2.3 结构体配置I2C 2.4 使能I2C 2.5 配置I2C外设总代码 三、指定地址写时序 3.1 生产起始条件S 3.2 监测EV5事件 3.3 发送从机地址 3.4 …

C语言程序设计十大排序—冒泡排序

文章目录 1.概念✅2.冒泡排序&#x1f388;3.代码实现✅3.1 直接写✨3.2 函数✨ 4.总结✅ 1.概念✅ 排序是数据处理的基本操作之一&#xff0c;每次算法竞赛都很多题目用到排序。排序算法是计算机科学中基础且常用的算法&#xff0c;排序后的数据更易于处理和查找。在计算机发展…

Python网络自动化运维---用户交互模块

文章目录 目录 文章目录 前言 实验环境准备 一.input函数 代码分段解析 二.getpass模块 前言 在前面的SSH模块章节中&#xff0c;我们都是将提供SSH服务的设备的账户/密码直接写入到python代码中&#xff0c;这样很容易导致账户/密码泄露&#xff0c;而使用Python中的用户交…

【后端开发】字节跳动青训营之性能分析工具pprof

性能分析工具pprof 一、测试程序介绍二、pprof工具安装与使用2.1 pprof工具安装2.2 pprof工具使用 资料链接&#xff1a; 项目代码链接实验指南pprof使用指南 一、测试程序介绍 package mainimport ("log""net/http"_ "net/http/pprof" // 自…

【Ubuntu】安装SSH启用远程连接

【Ubuntu】安装OpenSSH启用远程连接 零、安装软件 使用如下代码安装OpenSSH服务端&#xff1a; sudo apt install openssh-server壹、启动服务 使用如下代码启动OpenSSH服务端&#xff1a; sudo systemctl start ssh贰、配置SSH&#xff08;可跳过&#xff09; 配置文件 …

【模拟集成电路】锁相环(phase-locked loops,PLL)设计_环形振荡器相关(简)

0. 前言 未来将会不定时更新PLL相关的文章&#xff0c;主要目的是作为个人的学习笔记&#xff0c;关于锁相环的基础&#xff0c;可以参考《模拟CMOS集成电路设计_Behzad Razavi》后面几章的内容&#xff0c;下面的文章主要参考书籍是的英文书籍《DESIGN OF CMOS PHASE‑LOCKED …