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, 大家好,我是一代,今天给大家带来有关字符函数和字符串函数的有关知识 所属专栏:C语言 创作不易,望得到各位佬们的互三呦 一.字符函数 在C语言中有一些函数是专门为字符设计的,这些函数的使用都需要包含一个头文…...
【CKA模拟题】查询消耗CPU最多的Pod
题干 For this question, please set this context (In exam, diff cluster name) 对于此问题,请设置此上下文(在考试中,diff 集群名称) kubectl config use-context kubernetes-adminkubernetesFind the pod that consumes the …...
网络简略总结
目录 一、三次握手 四次挥手 1、三次握手:为了建立长链接进行交互即建立一个会话,使用http/https协议 2、四次挥手是一个断开连接释放服务器资源的过程 3、如果已经建立了连接,但是客户端突然出现故障了怎么办? 4、谁可以中断连接?客户端还是服务端还是都可以? 5、…...
如何处理错误情况
处理错误情况是确保自动窗帘系统稳定运行的重要一环。在编写代码时,你需要考虑可能发生的各种错误情况,并编写相应的错误处理代码。下面是一些处理错误情况的常见方法: (1)错误检测: 首先,你需要能够检测到错误的发生。…...
【Greenhills】MULTI IDE-GHS最新版本Compiler 23.5.4的兼容性问题
【更多软件使用问题请点击亿道电子官方网站查询】 1、 文档目标 关于GHS推出的最新编译器版本 Compiler 2023.5.4在GHS以前版本的MULTI IDE上面能否使用的问题 2、 问题场景 针对于,客户使用MULTI IDE 8.1.4以前的IDE版本,想要搭载使用最新版本的编译器…...
用连续自然数之和来表达整数 - 华为OD统一考试(C卷)
OD统一考试(C卷) 分值: 100分 题解: Java / Python / C++ 题目描述 一个整数可以由连续的自然数之和来表示。给定一个整数,计算该整数有几种连续自然数之和的表达式,且打印出每种表达式。 输入描述 一个目标整数T (1 <=T<= 1000) 输出描述 该整数的所有表达式…...
SQLiteC/C++接口详细介绍之sqlite3类(十二)
返回目录:SQLite—免费开源数据库系列文章目录 上一篇:SQLiteC/C接口详细介绍之sqlite3类(十一) 下一篇:SQLiteC/C接口详细介绍之sqlite3类(十三) 37.sqlite3_load_extension 用于在SQLit…...
linux系统--------------mysql数据库管理
目录 一、SQL语句 1.1SQL语言分类 1.2查看数据库信息 1.3登录到你想登录的库 1.4查看数据库中的表信息 1.5显示数据表的结构(字段) 1.5.1数据表的结构 1.5.2常用的数据类型: 二、关系型数据库的四种语言 2.1DDL:数据定义语言&am…...
网络——入门基础
目录 协议 网络协议 OSI七层模型 网络传输基本流程 网络传输流程图 局域网通信 数据包的封装和解包 广域网通信 网络地址管理 IP地址 MAC地址 协议 关于什么是局域网,什么是广域网,我这里就不过多赘述了,我们直接来谈一下什么…...
二、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语言的,不是windows操作系统的,和PATH环境变量完全不同classpath环境变量是给classloader(类加载器)指路的java A 。执行后,先启动JVM, JVM启动classload…...
Linux快速入门,上手开发 01.学习路线
少时曾许凌云志,当取世间第一流 再见少年拉满弓,不惧岁月不飓风 —— 24.3.20 1.Linux的发展历史 2.VM虚拟机的Linux初体验 3.图形化页面设置系统——快速上手 4.命令行操作——向专业前进 5.核心操作命令——必知必会(管理企业级权限/定位b…...
JSX return里面如何用if判断
在JSX中,由于不能直接使用传统的JavaScript if 语句,但可以通过条件渲染来实现类似的效果。以下是一些方法: 1. 三元运算符(Ternary Operator) 最简单的条件渲染方式是使用三元运算符: return (<div>{condition ? <ComponentIfTrue /> : <Com…...
Vulnhub靶机渗透:DC-7打靶记录
前言 自信自强,来自于不怕苦、不怕难的积淀。宝剑锋从磨砺出,梅花香自苦寒来;任何美好理想,都离不开筚路蓝缕、手胼足胝的艰苦奋斗! 靶场介绍 DC-7是一个初中级的靶场,需要具备以下前置知识:…...
目标检测---IOU计算详细解读(IoU、GIoU、DIoU、CIoU、EIOU、Focal-EIOU、SIOU、WIOU)
常见IoU解读与代码实现 一、✒️IoU(Intersection over Union)1.1 🔥IoU原理☀️ 优点⚡️缺点 1.2 🔥IoU计算1.3 📌IoU代码实现 二、✒️GIoU(Generalized IoU)2.1 GIoU原理☀️优点⚡️缺点 2…...
探索并发编程:深入理解线程池
文章目录 前言一、线程池是什么?二、如何创建线程池1.使用Executors类2.使用ThreadPoolExecutor类手动配置线程池 总结 前言 随着计算机系统的不断发展和进步,我们需要处理更多的并发任务和复杂的操作。而线程池作为一种高效的线程管理机制,…...
html5cssjs代码 023 公制计量单位进位与换算表
html5&css&js代码 023 公制计量单位进位与换算表 一、代码二、解释 这段HTML代码定义了一个网页,用于展示公制计量单位的进位与换算表。 一、代码 <!DOCTYPE html> <html lang"zh-cn"> <head><meta charset"utf-8&quo…...
UE5.3 StateTree使用实践
近期浏览UE的CitySample(黑客帝国Demo),发现有不少逻辑用到了StateTree学习一下,StateTree是多层状态机实现,以组件的形式直接挂载在蓝图中运行。 与平时常见的一些FSM库不同,StateTree并不会返回给外界当…...
【09】进阶JavaScript事件循环Promise
一、事件循环 浏览器的进程模型 何为进程? 程序运行需要有它自己专属的内存空间,可以把这块内存空间简单的理解为进程 每个应用至少有一个进程,进程之间相互独立,即使要通信,也需要双方同意。 何为线程? 有了进程后,就可以运行程序的代码了。 运行代码的「人」称之…...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...

