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

C语言字符函数和字符串函数详解

       Hello, 大家好,我是一代,今天给大家带来有关字符函数和字符串函数的有关知识

       所属专栏:C语言

       创作不易,望得到各位佬们的互三呦

一.字符函数

在C语言中有一些函数是专门为字符设计的,这些函数的使用都需要包含一个头文件<ctype.h>

如:(注:以下函数原型都很相似,都为int 函数(int 字符))

函数

iscntrl                       检查字符是否为可控制字符

isspace                    检查字符是否为一个空格、制表符、换行,换页’\f‘或回车

isdigit                       检查字符是否为数字’0‘-’9‘

isxdigit                     检查字符是否为16进制的字符包括所有10进制数字,小写字母,a-f,大                                  写字符A-F

islower                     检查字符是否为小写字母

isupper                    检查字符是否为大写字母

isalpha                     检查字符是否为可打印字符

isalnum                    检查字符是否为字母或十进制数字

ispunct                     检查字符是否为可打印标点字符(不属于数字和字母的图形字符)

isgraph                     检查字符是否为可打印字符(不包括空格)

isprint                       检查字符是否为可打印字符(包括空格)

以上函数当条件满足时的返回值都为非0的整数

如: islower(c),如果c是小写字母,返回非零整数,不是小写字母就返回0

#include<stdio.h>
#include<ctype.h>
int main()
{printf("%d", islower('b'));
}

二.字符转换函数

C语言提供了两种字符转换函数

1.int tolower(int c)    将传进去的大写字母转换为小写

2. int upper(int c)    将传进去的小写字母转换为大写

如:

#include<stdio.h>
#include<ctype.h>
int main()
{printf("%c", tolower('A'));//将大写字母转小写,如果不为大写字母则不改变
}

 三.字符串函数及字符串模拟

这里字符串函数包含的头文件都为string.h

一.strlen函数

函数原型:size_t strlen (const char*str)

头文件:string.h

功能:计算字符串长度(字符串以‘\0’为结束标志,strlen函数返回的是在字符串中‘\0’前面面出现的字符个数)

注意:1.参数指向的字符串必须以'\0'为结束标志,否则不知道字符串在哪里结束,返回随机值

2.函数的返回值为size_t , 是无符号的(下面会举相关例题)

就strlen的返回值有一个例题:

#include<stdio.h>
#include<string.h>
int main()
{const char* str1 = "acbdh";const char* str2 = "ads";if (strlen(str2) - strlen(str1) > 0){printf(">");}else{printf("<");}return 0;
}

这里很多人会认为输出的是<,但实际输出的是>,为什么呢?其实是以为strlen的返回值为size_t,其表示的数都为无符号数,也就是表示的为正数,比如-1,因为返回类型为size_t,其最高位的符号为表示的就为2的32次方,而不是表示正负号。

strlen函数模拟实现

方法1:指针减指针,指针减指针表示的是两个指针之间相差的元素个数

​
#include<stdio.h>
#include<assert.h>
size_t my_strlen(char*str)
{assert(str);//防止str为空指针,包含头文件为assert.hchar* p = str;while (*str != '\0'){str++;}return str - p;
}
int main()
{const char* str1 = "acbdh";printf("%zd", my_strlen(str1));return 0;
}​

 方法2:计数器方式,用count记录元素个数

#include<stdio.h>
#include<assert.h>
size_t my_strlen(const char* str)
{assert(str);//防止str为空指针,包含头文件为assert.hint count = 0;while (*str != '\0'){str++;count++;}return count;
}
int main()
{const char* str1 = "acbdh";printf("%zd", my_strlen(str1));return 0;
}

方法3:递归方式

#include<stdio.h>
#include<assert.h>
size_t my_strlen(const char* str)
{assert(str);//防止str为空指针,包含头文件为assert.hif (*str == '\0')return 0;return my_strlen(str + 1) + 1;
}
int main()
{const char* str1 = "acbdh";printf("%zd", my_strlen(str1));return 0;
}

二.strcpy函数

函数原型:char* strcpy(char* destination ,const char* source)

功能:把源字符串复制到目标字符串

注意:1.源字符必须以‘\0’结束

2.会将源字符串的‘\0’拷贝到目标空间

3.目标空间足够大,以确保能够存放源字符串

4.目标空间必须可修改

strcpy的模拟实现

​
#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* str1, char* str2)
{assert(str1 && str2);char* s = str1;while (*str1++ = *str2++);//先解引用在++return s;
}
int main()
{char str1[] = "acbdh";char* str2 = "acb";printf("%s", my_strcpy(str1,str2));return 0;
}​

三.strcat函数

函数原型:char* strcat(char*dest,const char*str)

功能:将两个字符串拼接起来,将str拼接到dest上

注意:1.源字符串必须以'\0'结束

2.目标字符串中也得有‘\0’,否则没办法知道从哪里开始拼接

3.目标空间足够大,能容纳下源字符的内容

4.目标空间必须可修改

strcat模拟实现

#include<stdio.h>
#include<assert.h>
char* my_strcat(char* str1,const char*str2)
{assert(str1&&str2);//防止str为空指针,包含头文件为assert.hchar* s = str1;while(*str1){str1++;}while (*str1++ = *str2++);//当*str2为'\0'时表达式结果为假return s;}
int main()
{char str1[20] = "acbdh";const char* str2 = "sad";printf("%s", my_strcat(str1,str2));return 0;
}

四.strcmp函数

函数原型:int strcmp(char*str1,char*str2)

功能:比较两个字符串的大小,若第一个字符串大于第二个字符串,则返回大于0的数字

第一个字符串小于第二个字符串,则返回小于0的数字

第一个字符串等于第二个字符串,则返回0

注意:比较两个字符串大小是用ascii值比较,一个一个字符比较

strcmp函数模拟

#include<stdio.h>
#include<assert.h>
int  my_strcmp(char* str1,const char*str2)
{assert(str1&&str2);//防止str为空指针,包含头文件为assert.hwhile (*str1 == *str2){if (*str1 == '\0')//代表*str1和*str2都为'\0'return 0;str1++;str2++;}return *str1 - *str2;
}
int main()
{const char *str1 = "acbdh";const char* str2 = "sad";printf("%d", my_strcmp(str1,str2));return 0;
}

 五.strncpy函数

函数原型:char* strncpy(char* destination,char *source,size_t num)

功能:拷贝num个字符从源字符串到目标空间

注意:如果源字符串的长度小于num,则拷贝完源字符后,到目标空间的后边追加'\0',直至num个

strncpy函数模拟

#include <stdio.h>
#include <string.h>
#include<assert.h>
char* my_strncpy(char* str1, const char* str2, size_t n)
{assert(str1 && str2);char* s = str1;for(int i=0;i<n && str2!='\0';i++){*str1++ = *str2++;}*str1 = '\0';return s;
}
int main()
{char str1[20]="name ";char str2[20]="str";printf("%s", my_strncpy(str1, str2, 1));
}

六.strncat函数

函数原型:char*strncat(char* destination ,const char*source ,size_t num)

功能 :将source指向字符串的前num个字符追加到destination指向的字符串末尾,再追加⼀个 \0 字符

注意:如果source 指向的字符串的长度小于num的时候,只会将字符串中到'\0'的内容追加到destination指向的字符串末尾

strncat模拟

#include<stdio.h>
#include<assert.h>
char* my_strncat(char* dest, char* str, size_t n)
{assert(dest && str);int i;char* s = dest;while (*dest != '\0'){dest++;}for (i = 0; i < n && str[i] != '\0'; i++){dest[i] = str[i];}dest[i] = '\0';return s;
}
int main()
{char str[] = { "abcd" };char dest[20] = { "mnkj***\0***" };char* ret = my_strncat(dest, str, 2);printf("%s", ret);
}

七.strncmp函数

函数原型:(const char*str1, const char*str2,size_t num)

功能: 比较str1和str2的前num个字符,如果相等就继续往后⽐较,最多比较num个字⺟,如果提前发现不一样,就提前结束。如果num个字符都相等,就是相等返回0,如果str字符串<str2字符串,就返回小于0的数,反之,返回大于0的数

strncmp函数模拟

#include<stdio.h>
#include<assert.h>
int  my_strncmp(const char* str1, const char* str2,size_t num)
{assert(str1 && str2);//防止str为空指针,包含头文件为assert.hwhile (*str1 == *str2&& num--){if (*str1 == '\0')//代表*str1和*str2都为'\0'return 0;str1++;str2++;}if (num == 0){return 0;}return *str1 - *str2;
}
int main()
{const char* str1 = "afbdh";const char* str2 = "afbh";printf("%d", my_strncmp(str1, str2, 9));return 0;
}

八.strstr函数

函数原型:char* strstr(const char *str1,const char*str2)

功能: 返回字符串str2在字符串str1中第⼀次出现的位置

strstr函数模拟

#include<stdio.h>
#include<assert.h>
char* my_strstr(const char* str1, const char* str2)
{assert(str1 && str2);const char* p1 = NULL;const char* p2 = NULL;const char* cur = str1;if (*str2 == '\0')return str1;while (*cur){p1 = cur;//记录str1开始的起始位置p2 = str2;//记录str2的位置while (*p1 == *p2 && *p1 != '\0' && *p2 != '\0'){p1++;p2++;}if (p2 == '\0'){return (char*)cur;//将const char*强转}if (*p1 == '\0'){return NULL;}cur++;//起始位置不可以,刷新起始位置}return NULL;}
int main()
{char a[] = { "abbbcde" };char b[] = { "bc" };printf("%s", my_strstr(a, b));
}

 九.strtok函数

函数原型:char* strtok(char*str1, const char*str2)

功能: 将str1进行分割,str2中包含分割符(第⼀个参数指定⼀个字符串,它包含了0个或者多个由str2字符串中⼀个或者多个分隔符分割的标记)

注意:1.strtok函数找到str1中出现的分割符,将其标记,并将其之前的字符串⽤ \0 结尾,返回⼀个指向这个标记的指针,下次用的时候第一个参数为NULL。(注: strtok函数会改变被操作的字符串,所以在使⽤strtok函数切分的字符串⼀般都是临时拷贝的内容 并且可修改。)

2.strtok函数的第⼀个参数不为 NULL ,函数将找到str中第⼀个标记,strtok函数将保存它在字符串中的位置。

3.strtok函数的第⼀个参数为 NULL ,函数将在同⼀个字符串中被保存的位置开始,查找下⼀个标记。

4.如果字符串中不存在更多的标记,则返回 NULL 指针。

strstr使用示例

#include<stdio.h>
#include<string.h>
int main()
{char a[] = { "zhju.sj@sj" };char* sep = ".@";char* str = NULL;for (str = strtok(a, sep); str != NULL; str = strtok(NULL, sep)){printf("%s\n", str);}
}

九.strerror函数

函数原型:char*strerror (int errnum)

功能:strerror函数可以把参数部分错误码对应的错误信息的字符串地址返回来。 在不同的系统和C语言标准库的实现中都规定了⼀些错误码,⼀般是放在 errno.h 这个头文件中说明 的,C语言程序启动的时候就会使⽤一个全面的变量errno来记录程序的当前错误码,只不过程序启动的时候errno是0,表示没有错误,当我们在使用标准库中的函数的时候发生了某种错误,就会讲对应 的错误码,存放在errno中,而⼀个错误码的数字是整数很难理解是什么意思,所以每⼀个错误码都是 有对应的错误信息的。strerror函数就可以将错误对应的错误信息字符串的地址返回。

相关文章:

C语言字符函数和字符串函数详解

Hello, 大家好&#xff0c;我是一代&#xff0c;今天给大家带来有关字符函数和字符串函数的有关知识 所属专栏&#xff1a;C语言 创作不易&#xff0c;望得到各位佬们的互三呦 一.字符函数 在C语言中有一些函数是专门为字符设计的&#xff0c;这些函数的使用都需要包含一个头文…...

【CKA模拟题】查询消耗CPU最多的Pod

题干 For this question, please set this context (In exam, diff cluster name) 对于此问题&#xff0c;请设置此上下文&#xff08;在考试中&#xff0c;diff 集群名称&#xff09; kubectl config use-context kubernetes-adminkubernetesFind the pod that consumes the …...

网络简略总结

目录 一、三次握手 四次挥手 1、三次握手:为了建立长链接进行交互即建立一个会话,使用http/https协议 2、四次挥手是一个断开连接释放服务器资源的过程 3、如果已经建立了连接,但是客户端突然出现故障了怎么办? 4、谁可以中断连接?客户端还是服务端还是都可以? 5、…...

如何处理错误情况

处理错误情况是确保自动窗帘系统稳定运行的重要一环。在编写代码时&#xff0c;你需要考虑可能发生的各种错误情况&#xff0c;并编写相应的错误处理代码。下面是一些处理错误情况的常见方法&#xff1a; (1)错误检测&#xff1a; 首先&#xff0c;你需要能够检测到错误的发生。…...

【Greenhills】MULTI IDE-GHS最新版本Compiler 23.5.4的兼容性问题

【更多软件使用问题请点击亿道电子官方网站查询】 1、 文档目标 关于GHS推出的最新编译器版本 Compiler 2023.5.4在GHS以前版本的MULTI IDE上面能否使用的问题 2、 问题场景 针对于&#xff0c;客户使用MULTI IDE 8.1.4以前的IDE版本&#xff0c;想要搭载使用最新版本的编译器…...

用连续自然数之和来表达整数 - 华为OD统一考试(C卷)

OD统一考试(C卷) 分值: 100分 题解: Java / Python / C++ 题目描述 一个整数可以由连续的自然数之和来表示。给定一个整数,计算该整数有几种连续自然数之和的表达式,且打印出每种表达式。 输入描述 一个目标整数T (1 <=T<= 1000) 输出描述 该整数的所有表达式…...

SQLiteC/C++接口详细介绍之sqlite3类(十二)

返回目录&#xff1a;SQLite—免费开源数据库系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;十一&#xff09; 下一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;十三&#xff09; ​37.sqlite3_load_extension 用于在SQLit…...

linux系统--------------mysql数据库管理

目录 一、SQL语句 1.1SQL语言分类 1.2查看数据库信息 1.3登录到你想登录的库 1.4查看数据库中的表信息 1.5显示数据表的结构&#xff08;字段&#xff09; 1.5.1数据表的结构 1.5.2常用的数据类型: 二、关系型数据库的四种语言 2.1DDL&#xff1a;数据定义语言&am…...

网络——入门基础

目录 协议 网络协议 OSI七层模型 网络传输基本流程 网络传输流程图 局域网通信 数据包的封装和解包 广域网通信 网络地址管理 IP地址 MAC地址 协议 关于什么是局域网&#xff0c;什么是广域网&#xff0c;我这里就不过多赘述了&#xff0c;我们直接来谈一下什么…...

二、yocto 集成ros2(基于raspberrypi 4B)

yocto 集成ros2 yocto 集成ros21. 下载ros layer2. 编译集成ros3. 功能验证 yocto 集成ros2 本篇文章为基于raspberrypi 4B单板的yocto实战系列的第二篇文章。 一、yocto 编译raspberrypi 4B并启动 本节我们将ros2机器人操作系统移植到我们的yocto系统里面。 1. 下载ros laye…...

html--bug

文章目录 html html <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>老师</title><style>body {background-color: #008000;margin: 0px;cursor: none;overflow: hidden;}</style></head><bod…...

Java基础学习笔记三

环境变量CLASSPATH classpath环境变量是隶属于java语言的&#xff0c;不是windows操作系统的&#xff0c;和PATH环境变量完全不同classpath环境变量是给classloader&#xff08;类加载器&#xff09;指路的java A 。执行后&#xff0c;先启动JVM&#xff0c; JVM启动classload…...

Linux快速入门,上手开发 01.学习路线

少时曾许凌云志&#xff0c;当取世间第一流 再见少年拉满弓&#xff0c;不惧岁月不飓风 —— 24.3.20 1.Linux的发展历史 2.VM虚拟机的Linux初体验 3.图形化页面设置系统——快速上手 4.命令行操作——向专业前进 5.核心操作命令——必知必会&#xff08;管理企业级权限/定位b…...

JSX return里面如何用if判断

在JSX中,由于不能直接使用传统的JavaScript ​​if​​ 语句,但可以通过条件渲染来实现类似的效果。以下是一些方法: 1. 三元运算符(Ternary Operator) 最简单的条件渲染方式是使用三元运算符: return (<div>{condition ? <ComponentIfTrue /> : <Com…...

Vulnhub靶机渗透:DC-7打靶记录

前言 自信自强&#xff0c;来自于不怕苦、不怕难的积淀。宝剑锋从磨砺出&#xff0c;梅花香自苦寒来&#xff1b;任何美好理想&#xff0c;都离不开筚路蓝缕、手胼足胝的艰苦奋斗&#xff01; 靶场介绍 DC-7是一个初中级的靶场&#xff0c;需要具备以下前置知识&#xff1a;…...

目标检测---IOU计算详细解读(IoU、GIoU、DIoU、CIoU、EIOU、Focal-EIOU、SIOU、WIOU)

常见IoU解读与代码实现 一、✒️IoU&#xff08;Intersection over Union&#xff09;1.1 &#x1f525;IoU原理☀️ 优点⚡️缺点 1.2 &#x1f525;IoU计算1.3 &#x1f4cc;IoU代码实现 二、✒️GIoU&#xff08;Generalized IoU&#xff09;2.1 GIoU原理☀️优点⚡️缺点 2…...

探索并发编程:深入理解线程池

文章目录 前言一、线程池是什么&#xff1f;二、如何创建线程池1.使用Executors类2.使用ThreadPoolExecutor类手动配置线程池 总结 前言 随着计算机系统的不断发展和进步&#xff0c;我们需要处理更多的并发任务和复杂的操作。而线程池作为一种高效的线程管理机制&#xff0c;…...

html5cssjs代码 023 公制计量单位进位与换算表

html5&css&js代码 023 公制计量单位进位与换算表 一、代码二、解释 这段HTML代码定义了一个网页&#xff0c;用于展示公制计量单位的进位与换算表。 一、代码 <!DOCTYPE html> <html lang"zh-cn"> <head><meta charset"utf-8&quo…...

UE5.3 StateTree使用实践

近期浏览UE的CitySample&#xff08;黑客帝国Demo&#xff09;&#xff0c;发现有不少逻辑用到了StateTree学习一下&#xff0c;StateTree是多层状态机实现&#xff0c;以组件的形式直接挂载在蓝图中运行。 与平时常见的一些FSM库不同&#xff0c;StateTree并不会返回给外界当…...

【09】进阶JavaScript事件循环Promise

一、事件循环 浏览器的进程模型 何为进程? 程序运行需要有它自己专属的内存空间,可以把这块内存空间简单的理解为进程 每个应用至少有一个进程,进程之间相互独立,即使要通信,也需要双方同意。 何为线程? 有了进程后,就可以运行程序的代码了。 运行代码的「人」称之…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

重启Eureka集群中的节点,对已经注册的服务有什么影响

先看答案&#xff0c;如果正确地操作&#xff0c;重启Eureka集群中的节点&#xff0c;对已经注册的服务影响非常小&#xff0c;甚至可以做到无感知。 但如果操作不当&#xff0c;可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

MinIO Docker 部署:仅开放一个端口

MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

Rust 开发环境搭建

环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行&#xff1a; rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu ​ 2、Hello World fn main() { println…...