文章目录

  • 一、字符分类函数
  • 二、字符转换函数
  • 三、strlen函数:计算字符串长度
    • 功能说明
    • 使用示例
    • 模拟实现
  • 四、strcpy函数:字符串拷贝
    • 功能说明
    • 模拟实现
  • 五、strcat函数:字符串追加
    • 功能说明
    • 模拟实现
  • 六、strcmp函数:字符串比较
    • 比较规则
    • 模拟实现
  • 七、strncpy函数:指定长度的字符串拷贝
    • 功能说明
  • 八、strncat函数:指定长度的字符串追加
    • 功能说明
  • 九、strncmp函数:指定长度的字符串比较
    • 功能说明
  • 十、strstr函数:查找子字符串
    • 功能说明
    • 模拟实现
  • 十一、strtok函数:字符串分割
    • 功能说明
  • 十二、strerror函数:获取错误信息
    • 功能说明
    • 相关函数:perror

在C语言编程中,字符和字符串的处理是非常基础且重要的操作。C语言标准库提供了一系列专门用于处理字符和字符串的库函数,掌握这些函数能极大地提高编程效率。本文将详细介绍这些函数的使用方法和模拟实现,帮助大家深入理解并灵活运用。

一、字符分类函数

字符分类函数用于判断一个字符属于哪种类型,它们都包含在ctype.h头文件中。这些函数的参数为 int类型 , 返回值为 非0(真)或0(假)

以下是常用的字符分类函数及其功能:

  • iscntrl:判断是否为控制字符
  • isspace:判断是否为空白字符(空格' '、换页'\f'、换行'\n'、回车'\r'、制表符'\t'、垂直制表符'\v'
  • isdigit:判断是否为十进制数字(0~9)
  • isxdigit:判断是否为十六进制数字(0~9、a~f、A~F)
  • islower:判断是否为小写字母(a~z)
  • isupper:判断是否为大写字母(A~Z)
  • isalpha:判断是否为字母(a~z或A~Z)
  • isalnum:判断是否为字母或数字(a~z、A~Z、0~9)
  • ispunct:判断是否为标点符号(不属于数字或字母的可打印图形字符)
  • isgraph:判断是否为任何图形字符
  • isprint:判断是否为任何可打印字符(包括图形字符和空白字符)

示例:使用islower函数
islower函数用于判断参数是否为小写字母,是则返回非0整数,否则返回0。

下面的代码将字符串中的小写字母转换为大写,其他字符不变:

#include <stdio.h>
#include <ctype.h>
int main ()
{int i = 0;char str[] = "Test String.\n";char c;while (str[i]){c = str[i];if (islower(c)) c -= 32;putchar(c);i++;}return 0;
}

二、字符转换函数

C语言提供了两个常用的字符转换函数,同样包含在ctype.h头文件中:

  • int tolower(int c):将大写字母转换为小写
  • int toupper(int c):将小写字母转换为大写

示例:使用toupper函数
将上面的小写转大写代码用toupper函数改写:

#include <stdio.h>
#include <ctype.h>
int main ()
{int i = 0;char str[] = "Test String.\n";char c;while (str[i]){c = str[i];if (islower(c)) c = toupper(c);putchar(c);i++;}return 0;
}

三、strlen函数:计算字符串长度

strlen函数用于计算字符串的长度,其原型为:
size_t strlen(const char *str);

功能说明

  • 字符串以’\0’作为结束标志,strlen返回的是’\0’前面的字符个数(不包含’\0’)
  • 参数指向的字符串必须以’\0’结束
  • 返回值为size_t(无符号整数),这一点在使用时容易出错

使用示例

#include <stdio.h>
#include <string.h>
int main()
{const char* str1 = "abcdef";const char* str2 = "bbb";if(strlen(str2) - strlen(str1) > 0)printf("str2>str1\n");elseprintf("str1>str2\n");return 0;
}

注意:由于strlen返回值是无符号数,上面代码中strlen(str2)-strlen(str1)的结果是无符号数,可能会出现与预期不符的情况。

模拟实现

strlen有多种模拟实现方式:

  1. 计数器方式
int my_strlen(const char *str)
{int count = 0;assert(str); // 确保指针非空while(*str){count++;str++;}return count;
}
  1. 递归方式(不创建临时变量)
int my_strlen(const char *str)
{assert(str);if(*str == '\0')return 0;elsereturn 1 + my_strlen(str + 1);
}
  1. 指针-指针方式
int my_strlen(char *s)
{assert(s);char *p = s;while(*p != '\0')p++;return p - s;
}

四、strcpy函数:字符串拷贝

strcpy函数用于将源字符串拷贝到目标空间,原型为:
char* strcpy(char *destination, const char *source);

功能说明

  • 源字符串必须以’\0’结束
  • 会将源字符串中的’\0’拷贝到目标空间
  • 目标空间必须足够大,以容纳源字符串
  • 目标空间必须可修改

模拟实现

char *my_strcpy(char *dest, const char*src)
{char *ret = dest;assert(dest != NULL);assert(src != NULL);while((*dest++ = *src++)){;}return ret;
}

实现说明:循环中先将*src赋值给*dest,然后两者都自增,直到拷贝到’\0’时,循环条件为假,结束循环。

五、strcat函数:字符串追加

strcat函数用于将源字符串追加到目标字符串末尾,原型为:
char *strcat(char *destination, const char *source);

功能说明

  • 源字符串必须以’\0’结束
  • 目标字符串也必须以’\0’结束,否则无法确定追加的起始位置
  • 目标空间必须足够大,能容纳源字符串的内容
  • 目标空间必须可修改
  • 字符串不能自己给自己追加,会导致错误

模拟实现

char *my_strcat(char *dest, const char*src)
{char *ret = dest;assert(dest != NULL);assert(src != NULL);// 找到目标字符串的结束标志'\0'while(*dest){dest++;}// 追加源字符串while((*dest++ = *src++)){;}return ret;
}

六、strcmp函数:字符串比较

strcmp函数用于比较两个字符串的大小,原型为:
int strcmp(const char *str1, const char *str2);

比较规则

  • 从第一个字符开始比较,若相等则继续比较下一对字符,直到字符不同或遇到’\0’
  • 标准规定:
    • 第一个字符串大于第二个字符串,返回大于0的数字
    • 两个字符串相等,返回0
    • 第一个字符串小于第二个字符串,返回小于0的数字
  • 比较的是对应位置字符的ASCII码值

模拟实现

int my_strcmp(const char *str1, const char *str2)
{assert(str1 != NULL);assert(str2 != NULL);while(*str1 == *str2){if(*str1 == '\0')return 0;str1++;str2++;}return *str1 - *str2;
}

七、strncpy函数:指定长度的字符串拷贝

strncpy函数可以指定拷贝的字符个数,原型为:
char *strncpy(char *destination, const char *source, size_t num);

功能说明

  • 拷贝num个字符从源字符串到目标空间
  • 如果源字符串的长度小于num,则拷贝完源字符串后,在目标空间后追加0,直到达到num个字符

八、strncat函数:指定长度的字符串追加

strncat函数用于将源字符串的前num个字符追加到目标字符串,原型为:
char *strncat(char *destination, const char *source, size_t num);

功能说明

  • 将源字符串的前num个字符追加到目标字符串末尾,并追加一个’\0’
  • 如果源字符串的长度小于num,则只追加到源字符串的’\0’为止

使用示例

#include <stdio.h>
#include <string.h>
int main ()
{char str1[20];char str2[20];strcpy(str1,"To be ");strcpy(str2,"or not to be");strncat(str1, str2, 6);printf("%s\n", str1); // 输出 "To be or not"return 0;
}

九、strncmp函数:指定长度的字符串比较

strncmp函数用于比较两个字符串的前num个字符,原型为:
int strncmp(const char *str1, const char *str2, size_t num);

功能说明

  • 比较两个字符串的前num个字符
  • 如果相等则继续比较,最多比较num个字符
  • 如果提前发现不同,则提前结束比较
  • 返回值规则与strcmp相同
返回值说明
<0第一个不匹配的字符在str1中的值小于在str2中的值
0两个字符串的前num个字符相等
>0第一个不匹配的字符在str1中的值大于在str2中的值

十、strstr函数:查找子字符串

strstr函数用于查找一个字符串在另一个字符串中第一次出现的位置,原型为:
char *strstr(const char *str1, const char *str2);

功能说明

  • 返回字符串str2在字符串str1中第一次出现的位置的指针
  • 如果str2不是str1的一部分,则返回空指针
  • 匹配过程不包含’\0’,以’\0’作为结束标志

使用示例

#include <stdio.h>
#include <string.h>
int main ()
{char str[] = "This is a simple string";char *pch;pch = strstr(str, "simple");strncpy(pch, "sample", 6);printf("%s\n", str); // 输出 "This is a sample string"return 0;
}

模拟实现

char *strstr(const char *str1, const char *str2)
{char *cp = (char *)str1;char *s1, *s2;if (!*str2)return (char *)str1;while (*cp){s1 = cp;s2 = (char *)str2;while (*s1 && *s2 && !(*s1 - *s2)){s1++;s2++;}if (!*s2)return cp;cp++;}return NULL;
}

十一、strtok函数:字符串分割

strtok函数用于分割字符串,原型为:
char *strtok(char *str, const char *sep);

功能说明

  • sep参数是一个字符串,定义了用作分隔符的字符集合
  • 第一个参数为str时,函数找到str中的第一个标记,并用’\0’结尾,返回指向该标记的指针,同时保存该位置
  • 第一个参数为NULL时,函数从上次保存的位置继续查找下一个标记
  • 如果没有更多标记,返回NULL
  • strtok会修改被操作的字符串,所以通常对字符串的临时拷贝进行操作

使用示例

#include <stdio.h>
#include <string.h>
int main()
{char arr[] = "192.168.6.111";char* sep = ".";char* str = NULL;for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep)){printf("%s\n", str);}return 0;
}
// 输出:
// 192
// 168
// 6
// 111

十二、strerror函数:获取错误信息

strerror函数用于获取错误码对应的错误信息,原型为:
char *strerror(int errnum);

功能说明

  • 参数errnum为错误码,函数返回该错误码对应的错误信息字符串的地址
  • 错误码通常定义在errno.h头文件中
  • 程序启动时,errno(记录当前错误码的变量)为0,表示没有错误
  • 当标准库函数发生错误时,会将对应的错误码存入errno

使用示例

  1. 打印0~10的错误码对应的信息
#include <errno.h>
#include <string.h>
#include <stdio.h>
int main()
{int i = 0;for (i = 0; i <= 10; i++) {printf("%s\n", strerror(i));}return 0;
}

在Windows11+VS2022环境下的输出如下:

No error
Operation not permitted
No such file or directory
No such process
Interrupted function call
Input/output error
No such device or address
Arg list too long
Exec format error
Bad file descriptor
No child processes
  1. 在文件操作中使用
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main ()
{FILE *pFile;pFile = fopen("unexist.ent", "r");if (pFile == NULL)printf("Error opening file unexist.ent: %s\n", strerror(errno));return 0;
}
// 输出:Error opening file unexist.ent: No such file or directory

相关函数:perror

perror函数可以直接打印错误信息,它会先打印参数中的字符串,再打印一个冒号和空格,最后打印错误信息。

#include <stdio.h>
#include <errno.h>
int main ()
{FILE *pFile;pFile = fopen("unexist.ent", "r");if (pFile == NULL)perror("Error opening file unexist.ent");return 0;
}
// 输出:Error opening file unexist.ent: No such file or directory

本文详细介绍了C语言中常用的字符函数和字符串函数,包括它们的功能、使用方法和模拟实现。这些函数在日常编程中非常实用,掌握它们能帮助我们更高效地处理字符和字符串操作。在使用过程中,要注意各个函数的参数要求和返回值特点,避免出现不必要的错误。

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

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

相关文章

uvicorn 启动重复加载 多次加载

目录 uvicorn 启动重复加载 多次加载 解决方法1&#xff1a; 解决方法2&#xff1a; uvicorn 启动重复加载 多次加载 fastapi_aa 是当前类 解决方法1&#xff1a; import uvicornfrom fastapi import FastAPIapp FastAPI()if __name__ "__main__":if sys.gett…

Bard AI本地部署教程:在自己的服务器上运行谷歌AI

Bard AI本地部署教程:在自己的服务器上运行谷歌AI 关键词:Bard AI、本地部署、服务器、谷歌AI、运行教程 摘要:本文旨在为大家详细介绍如何在自己的服务器上实现Bard AI的本地部署。我们会从背景知识讲起,逐步深入到核心概念、算法原理、操作步骤,还会提供项目实战案例和实…

应急响应处置案例(上)

本文目录 目录 本文目录 Web安全事件 概述 案例1 - webshell 背景 排查情况 天眼 服务器 案例2 - Struts2 排查情况 天眼 服务器 案例3 - Redis未授权 背景 排查情况 天眼 服务器 案例4 - EW内网穿透 背景 排查情况 天眼 服务器 案例5 - 一句话木马 背…

面试官问我:“为什么不能完全用对象替代指针?”我笑了:看看Google和Linux内核代码就知道了!

本篇摘要 本篇将以最通俗易懂的语言&#xff0c;形象的讲述为什么很多情境下&#xff0c;我们优先考虑的使用指针而不是对象本身&#xff0c;本篇将给出你答案&#xff01; 一.从一个生活例子说起&#xff0c;形象秒懂 想象一下&#xff0c;你去图书馆借书&#xff0c;下面你…

CAMx大气污染模拟全流程:Linux编译/多重嵌套配置/SMOKE清单预处理/SA-DDM-PA工具应用与科研绘图结果可视化分析

CAMx模型是一个基于大气化学&#xff0c;针对臭氧、颗粒物和雾霾天气过程的大气污染物计算模型。【目标】&#xff1a;1、掌握CAMx模式的区域空气质量模拟案例配置技术方法2、掌握SMOKE模型的CAMx模式大气排放清单输入准备方法3、掌握CAMx模式污染来源解析工具&#xff08;SA&a…

嵌入式学习笔记-MCU阶段-DAY10ESP8266模块

1.ESP8266概述 官方网址&#xff1a;ESP8266 Wi-Fi MCU I 乐鑫科技 (espressif.com.cn) ESP8266模块---wifi模块 产品特点&#xff1a; 2.ESP8266中的wifi: ESP8266EX ⽀持 TCP/IP 协议&#xff0c;完全遵循 802.11 b/g/n WLAN MAC 协议&#xff0c;⽀持分布式控制功能 (DC…

如何快速通过软件项目验收,第三方软件检测机构的重要性

在客户和开发团队之间&#xff0c;最后临门一脚的项目验收环节总容易出现各种问题&#xff0c;以至于时间无限拉长&#xff0c;久久不见结束&#xff0c;为此给大家准备了一份如何快速通过软件项目验收的内容来帮助大家结束持久战。 一、项目验收准备材料 &#xff08;一&…

洛谷做题3:P5711 【深基3.例3】闰年判断

文章目录题目描述输入格式输出格式输入输出样例分析代码题目描述 输入一个年份&#xff0c;判断这一年是否是闰年&#xff0c;如果是输出 1&#xff0c;否则输出 0。 1582 年以来&#xff0c;闰年的定义&#xff1a; 普通闰年&#xff1a;公历年份是 4 的倍数&#xff0c;且不…

PMP证书可以挂靠吗?怎么挂靠?

哈喽学弟学妹们&#xff0c;作为过来人&#xff0c;今天想跟大家聊聊 PMP 证书挂靠这事儿 —— 可能不少准备考或者刚考完的同学都琢磨过&#xff0c;但学长得跟你们交个底&#xff1a;这事儿真不行&#xff0c;更别提啥挂靠费了。先说说 PMP 证书本身哈&#xff0c;它是美国 P…

91-基于Spark的空气质量数据分析可视化系统

基于Spark的空气质量数据分析可视化系统设计与实现 项目概述 本项目是一个基于Apache Spark的大数据分析和可视化系统&#xff0c;专门用于空气质量数据的采集、分析、预测和可视化展示。系统采用分布式计算架构&#xff0c;结合机器学习算法&#xff0c;实现了对全国12个主要…

leetcode 2419. 按位与最大的最长子数组 中等

给你一个长度为 n 的整数数组 nums 。考虑 nums 中进行 按位与&#xff08;bitwise AND&#xff09;运算得到的值 最大 的 非空 子数组。换句话说&#xff0c;令 k 是 nums 任意 子数组执行按位与运算所能得到的最大值。那么&#xff0c;只需要考虑那些执行一次按位与运算后等于…

Git 命令使用指南:从入门到进阶

目录1. Git 基本操作1.1 添加文件到暂存区1.2 提交更改到本地仓库1.3 查看工作区状态1.4 查看提交历史1.5 查看引用日志&#xff08;包括已删除的记录&#xff09;2. 版本回退与撤销2.1 版本回退2.2 查看已删除的提交记录3. 分支管理3.1 查看分支3.2 创建并切换到新分支3.3 合并…

SQL数据库连接Python实战:疫情数据指挥中心搭建指南

SQL数据库连接Python实战&#xff1a;疫情数据指挥中心搭建指南从WHO数据集到实时仪表盘&#xff0c;构建工业级疫情监控系统一、疫情数据指挥中心&#xff1a;全球健康危机的中枢神经​​疫情数据价值​​&#xff1a;全球每日新增病例&#xff1a;50万疫苗接种数据&#xff1…

参赛单位条件放宽!2025年“数据要素 ×”大赛福建分赛厦门赛区赛事有新调整

各位伙伴们 想抓住数据价值机遇 在行业赛场上崭露头角吗&#xff1f; 2025年“数据要素”大赛 福建分赛厦门赛区已启动 这份超全赛事解读 带你一站式摸清参赛关键&#xff01; 01 参赛单位要求放宽 经省分赛组委会与国家赛事组委会沟通&#xff0c;不具有独立法人资格的…

BasicAuthenticationFilter处理 HTTP 基本认证(Basic Authentication)的核心过滤器详解

BasicAuthenticationFilter处理 HTTP 基本认证&#xff08;Basic Authentication&#xff09;的核心过滤器详解在 Spring Security 中&#xff0c;BasicAuthenticationFilter 是​​处理 HTTP 基本认证&#xff08;Basic Authentication&#xff09;的核心过滤器​​&#xff0…

Next.js 中使用 MongoDB 完整指南

1. 安装依赖npm install mongodb # 或者使用 mongoose&#xff08;ODM&#xff09; npm install mongoose2. 数据库连接配置使用原生 MongoDB 驱动创建 lib/mongodb.js 文件&#xff1a;import { MongoClient } from mongodbconst uri process.env.MONGODB_URI const options …

嵌入式系统教学范式演进:云端仿真平台如何重构温湿度监测实验教学

在嵌入式系统开发的教学中&#xff0c;环境温湿度监测实验是经典的入门项目。它涉及传感器原理、外设驱动、数据采集和通信协议等核心知识点。然而传统实验模式面临硬件成本高、调试周期长、设备易损坏等痛点。学生往往因接线错误或代码bug导致传感器或开发板烧毁&#xff0c;不…

1.6万 Star 的流行容器云平台停止开源

什么是 KubeSphere &#xff1f; KubeSphere 是面向云原生应用的容器混合云。 KubeSphere 愿景是打造一个以 Kubernetes 为内核的云原生分布式操作系统&#xff0c;它的架构可以非常方便地使第三方应用与云原生生态组件进行即插即用&#xff08;plug-and-play&#xff09;的集成…

广东省省考备考(第六十三天8.1)——资料分析、数量(强化训练)

资料分析 错题解析解析解析今日题目正确率&#xff1a;80% 数量关系&#xff1a;数学运算 错题解析解析标记题解析解析解析今日题目正确率&#xff1a;87%

Agents-SDK智能体开发[3]之多Agent执行流程

文章目录说明Agents SDK基础Handoffs功能实现Handoffs简单示例&#x1f31f; 运行结果整理&#x1f4dd; 执行过程概述&#x1f4cb; 运行结果事件一&#xff1a;分诊智能体创建转交请求事件事件二&#xff1a;转交响应事件事件三&#xff1a;目标 Agent 响应请求并完成任务改进…