C语言_字符函数和字符串函数

1. 字符函数

1.1 字符分类函数

在C语言中,有一系列专门做字符分类的函数被包括在头文件<ctype.h>

这些函数的区分范围如下:

函数如果他的参数符合下列条件就返回真
iscntrl任何控制字符
isspace空白字符:空格’ ‘、换页’\n‘、回车’\r‘、制表符’\t‘ 、垂直制表符’\v‘
isdigit十进制数字 ’0‘ ~ ’9‘ 字符
isxdigit十六进制数字,包括所有十进制数字字符,大写字母 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任何可打印字符,包括图形字符和空白字符

我们来举一个例子来说明这些函数的用法:

int isupper(int C);

isupper函数可以判断参数部分的C是否属于大写字母范围。如果是就返回非0整数,如果不是就返回0。

应用
将字符串中的大写字母转小写,其他字符不变。

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

1.2 字符转换函数

字符转换函数可以大写转小写、小写转大写

函数使用形式如下:

int tolower(int C);
int toupper(int c);

函数应用如下:

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

2. 字符串函数

字符串函数的使用都需要包含头文件<string.h>

2.1 strlen的使用及模拟实现

函数形式如下:

size_t strlen(const char* str);

函数解析及注意事项:

  • strlen函数返回的是在字符串中 \0前面出现的字符个数(不包括 \0
  • 参数指向的字符串必须要以 \0结束
  • 函数的返回值为size_t(无符号整形)
  • strlen的使用要包含头文件<string.h>

函数的模拟实现:
(1)计数器方式

int my_strlen(const char* str) {int count = 0;assert(str);while (*str) {str++;count++;}
}int main() {char* ch = "abcdef";printf("%d", strlen(ch));
}

(2)不创建临时变量,运用函数递归

int my_strlen(const char* str) {assert(str);if (*str == '\0')return 0;elsereturn 1 + my_strlen(str + 1);
}int main() {char* ch = "123456";printf("%d",my_strlen(ch));
}

(3)指针 - 指针

int my_strlen(const char* str) {assert(str);char* p = str;while (*p != 0) {p++;}return p - str;
}int main() {char* ch = "123456";printf("%d",my_strlen(ch));
}

2.2 strcpy的使用及模拟实现

函数形式如下:

char* strcpy(char* destination, const char* source);

函数解析及注意事项:

  • strcpy函数的作用是将源字符串拷贝到目标字符串
  • 源字符串必须以 \0 结束
  • 源字符串的\0也会被拷贝到目标空间
  • 目标空间必须足够大,确保能存放源字符串
  • 目标空间必须可修改

函数的模拟实现:

char* my_strcpy(char* dest, char* src) {assert(dest);assert(src);char* ret = dest;while (*dest++ = *src++) {;}return ret;
}int main() {char d[] = "abcdef";char* s = "123";printf("%s", my_strcpy(d, s));return 0;
}

2.3 strcat的使用及模拟实现

函数形式如下:

char* strcat(char* destination, const char* source);

函数解析及注意事项:

  • strcat函数的作用是将源字符串追加到目标字符串的后面
  • 源字符串必须以\0结束
  • 目标字符串中也得有\0,否则没办法知道追加从哪里开始
  • 目标空间必须足够的大,能容纳两个字符串的内容
  • 目标空间必须可修改

函数的模拟实现:

char* my_strcat(char* dest, char* src) {assert(dest);assert(src);char* ret = dest;while (*dest) {dest++;}while (*dest++ = *src++) {;}return ret;
}int main() {char d[10] = "abcdef";char* s = "123";printf("%s", my_strcat(d, s));return 0;
}

2.4 strcmp的使用及模拟实现

函数形式如下:

int strcmp(const char* str1, const char* str2);

函数解析及注意事项:

  • strcmp函数的作用是比较两个字符串的大小(比较两个字符串中对应位置上字符ASCII码值的大小)
  • 第一个字符串大于第二个字符串,则返回大于0的数字
  • 第一个字符串等于第二个字符串,则返回0
  • 第一个字符串小于第二个字符串,则返回小于0的数字

函数的模拟实现:

int my_strcmp(char* str1, char* str2) {assert(str1);assert(str2);while (*str1 == *str2) {if (*str1 == '\0') {return 0;}str1++;str2++;}return *str1 - *str2;
}int main() {char* ch1 = "abcdef";char* ch2 = "abcf";if (my_strcmp(ch1, ch2) > 0) {printf("ch1 > ch2");}else if (my_strcmp(ch1, ch2) < 0) {printf("ch1 < ch2");}else {printf("ch1 == ch2");}return 0;
}

2.5 strstr的使用及模拟实现

函数的形式如下:

char* strstr(const char* str1, const char* str2);

函数解析及注意事项:

  • strstr函数的作用是返回字符串str2在字符串str1中第一次出现的位置
  • 字符串的比较匹配不包括\0字符,以``\0`作为结束标志

函数的模拟实现:

char* my_strstr(const char* str1, const char* str2) {char* cp = (char*)str1;if (!*str2)return (char*) str1;while (*cp) {//外循环用来刷新开始比较匹配的位置char* s1 = cp;char* s2 = (char*)str2;while (*s1 && *s2 && !(*s1 - *s2)) {//内循环用来比较匹配s1++;s2++;}if (!*s2)//如果s2为\0,说明比较匹配成功return cp;cp++;}return NULL;//如果外层循环已经遍历了一遍还未执行循环内的if语句的话,则说明匹配失败,返回空指针
}

2.6 strncpy的使用

函数形式如下:

char* strncpy(char* destination, const char* source, size_t num);

函数的解析及注意事项:

  • strncpy函数的作用是从源字符串拷贝num个字符到目标空间
  • 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后面追加0,直到num

2.7 strncat的使用

函数的形式如下:

char* strncat(char* destination, const char* source, size_t num);

函数的解析及注意事项:

  • strncat函数的作用是将源字符串的前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",str1);	return 0;
}

2.8 strncmp的使用

函数形式如下:

int strcmp(const char* str1, const char* str2, size_t num);

函数的解析及注意事项:

  • strncmp函数的作用是比较str1str2的前num个字符(比较相应位置字符的ASCII码值)
  • 比较的规则与strcmp相同。

2.9 strtok的使用

函数的形式如下:

char* strtok(char* str, const char* sep);

函数的解析及注意事项:

  • strtok函数的作用是将一个字符串分割成几个子字符串
  • sep参数指向一个用作分隔符的字符串
  • 第一个参数指定一个字符串,它包含了0个或多个由sep字符串中一个或多个分隔符分割的标记
  • strtok函数找到str中的一个标记,并将其用\0收尾,返回一个指向这个标记的指针
  • strtok函数的第一个参数不为NULL时,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置
  • strtok函数的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记
  • 如果字符串中不存在更多的标记,返回NULL

注:strtok函数会改变被操作的字符串,所以被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;
}

2.10 strerror的使用

函数形式如下:

char* strerror(int errnum);

函数底层逻辑及作用:

  • 底层逻辑:在不同的系统和C语言标准库的实现中都规定了一些错误码,放在<errno.h>头文件中,C语言程序启动的时候就会使用一个全局的整型变量errno来记录程序的当前错误码,当程序启动的时候errno0,表示没有错误,当我们在使用标准库中的函数发生错误时,就会减对应的错误码(一个整数)存放在errno中。每个错误码都对应着一个错误信息。
  • 作用strerror函数的作用是把参数部分的错误码对应的错误信息的字符串地址返回。

函数的使用:

#include<stdio.h>
#include<string.h>
#include<errno.h>int main(){FILE* pfile = fopen("unexist.ent","r");if(pfile == NULL)printf ("Error opening file unexist.ent: %s\n", strerror(errno));return 0;
}

同时我们也可以了解一下perror函数,perror函数等同于一次将上方代码中的第9行。

#include<stdio.h>
#include<string.h>
#include<errno.h>int main(){FILE* pfile = fopen("unexist.ent","r");if(pfile == NULL)perror("Error opening file unexist.ent");return 0;
}

今天的介绍就到这里,还要请各位佬儿们多多支持,多多点赞

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

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

相关文章

Oracle架构之数据库备份和RAC介绍

文章目录 1 数据库备份1.1 数据库备份分类1.1.1 逻辑备份与物理备份1.1.2 完全备份/差异备份/增量备份 1.2 Oracle 逻辑备份1.2.1 EXP/IMP1.2.1.1 EXP导出1.2.1.2 EXP关键字说明1.2.1.3 导入1.2.1.4 IMP关键字说明 1.2.2 EXPDP/IMPDP1.2.2.1 数据泵介绍1.2.2.2 数据泵的使用 1.…

【STM32单片机_(HAL库)】4-3-2【定时器TIM】测量按键按下时间1——编程实现捕获功能

测量按键按下时长思路 测量按键按下时间实验目的 使用定时器 2 通道 2 来捕获按键 &#xff08;按键接PA0&#xff09;按下时间&#xff0c;并通过串口打印。 计一个数的时间&#xff1a;1us&#xff0c;PSC71&#xff0c;ARR65535 下降沿捕获、输入通道 2 映射在 TI2 上、不分…

TypeScript快速梳理

为何需要TypeScript ts存在静态类型检查&#xff1a;在代码运行前进行检查&#xff0c;发现代码的错误或不合理之处&#xff0c;减少运行时异常的出现的几率&#xff0c;此种检查叫静态类型检查&#xff0c; TypeScript的核心就是静态类型检查&#xff0c;简言之就是把运行时的…

汽车发动机控制存储芯片MR2A08A

MRAM在汽车发动机控制单元中的关键数据存储&#xff0c;MR2A08A容量4Mb的非易失性存储芯片&#xff0c;符合汽车AEC-Q100 1级合格选项&#xff0c;可以在遇到的非常高的温度环境下工作&#xff0c;足够快地实时读取或写入数据&#xff0c;是非易失性的。 MRAM速度快&#xff0…

华为-单臂路由

1、什么是单臂路由 单臂路由&#xff08;Single-Arm Routing&#xff09;是一种网络架构和配置技术&#xff0c;它允许路由器通过一个物理接口来管理多个虚拟局域网&#xff08;VLAN&#xff09;之间的通信。 这个物理接口被配置为Trunk模式&#xff0c;以便能够传输来自不同VL…

Redis缓存淘汰算法详解

文章目录 Redis缓存淘汰算法1. Redis缓存淘汰策略分类2. 会进行淘汰的7种策略2.1 基于过期时间的淘汰策略2.2 基于所有数据范围的淘汰策略 3. LRU与LFU算法详解4. 配置与调整5. 实际应用场景 LRU算法以及实现样例LFU算法实现1. 数据结构选择2. 访问频率更新3. 缓存淘汰4. 缓存插…

如何从huggingface下载

我尝试了一下若干步骤&#xff0c;莫名奇妙就成功了 命令行代理 如果有使用魔法上网&#xff0c;可以使用命令行代码&#xff0c;解决所有命令行连不上外网的问题&#xff1a; #配置http git config --global http.proxy 127.0.0.1:xxxx git config --global https.proxy 127…

移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——15.红黑树

1.红黑树的概念 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上增加一个存储位表示结点的颜色&#xff0c;可以是Red或 Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制&#xff0c;红黑树确保没有一条路 径会比其他路径长出俩倍&#xff0c;…

专访 Bitlayer 联合创始人 Charlie:探索比特币 Layer2 技术的未来

整理&#xff1a;Tia&#xff0c;Techub News 在加密货币行业经历了近 10 年的风雨历程后&#xff0c;Bitlayer 联合创始人 Charlie Hu 凭借其在以太坊、波卡等顶级项目中的深厚经验&#xff0c;重新聚焦比特币生态&#xff0c;他与 Bitlayer 的另外一位联合创始人 Kevin He 通…

k8s搭建双主的mysql8集群---无坑

《k8s搭建一主三从的mysql8集群---无坑-CSDN博客》通过搭建一主三从&#xff0c;我们能理解到主节点只有1个&#xff0c;那么承担增删改主要还是主节点&#xff0c;如果你在从节点上去操作增删改操作&#xff0c;数据不会同步到其他节点。本章我们将实现多主&#xff08;双主&a…

YOLO11关键改进与网络结构图

目录 前言&#xff1a;一、YOLO11的优势二、YOLO11网络结构图三、C3k2作用分析四、总结 前言&#xff1a; 对于一个科研人来说&#xff0c;发表论文水平的高低和你所掌握的信息差有着极大的关系&#xff0c;所以趁着YOLO11刚刚发布&#xff0c;趁热了解&#xff0c;先人一步对…

Linux-基础实操篇-组管理和权限管理(上)

Linux 组基本介绍 在 linux 中的每个用户必须属于一个组&#xff0c;不能独立于组外。在 linux 中每个文件 有所有者、所在组、其它组的概念。 用户和组的基本概念&#xff1a; 用户名&#xff1a;用来识别用户的名称&#xff0c;可以是字母、数字组成的字符串&#xff0…

(Kafka源码五)Kafka服务端处理消息

Kafka 服务端&#xff08;Broker&#xff09;采用 Reactor 的架构思想&#xff0c;通过1 个 Acceptor&#xff0c;N 个 Processor(N默认为3)&#xff0c;M 个 KafkaRequestHandler&#xff08;M默认为8&#xff09;&#xff0c;来处理客户端请求&#xff0c;这种模式结合了多线…

kubeadm部署k8s集群,版本1.23.6;并设置calico网络BGP模式通信,版本v3.25--未完待续

1.集群环境创建 三台虚拟机&#xff0c;一台master节点&#xff0c;两台node节点 (根据官网我们知道k8s 1.24版本之后就需要额外地安装cri-dockerd作为桥接才能使用Docker Egine。经过尝试1.24后的版本麻烦事很多&#xff0c;所以此处我们选择1.23.6版本) 虚拟机环境创建参考…

【Android】浅析六大设计原则

【Android】浅析六大设计原则 六大设计原则是软件开发中常用的设计原则&#xff0c;用来帮助开发者编写灵活、可维护、可扩展的代码。它们是面向对象设计&#xff08;OOD&#xff09;的核心&#xff0c;遵循这些原则能够避免代码中的常见问题&#xff0c;比如代码难以修改、难…

Vue页面,基础配置

最简单页面 日期范围及字符搜索&#xff0c;监听器处理日期范围搜索控件清空重置问题导出、导出文件文件名称带日期时间表格日期指定格式显示。。。 <template><div class"app-container"><el-form :model"queryParams" ref"queryForm…

YOLOv11改进策略【损失函数篇】| Shape-IoU:考虑边界框形状和尺度的更精确度量

一、本文介绍 本文记录的是改进YOLOv11的损失函数&#xff0c;将其替换成Shape-IoU。现有边界框回归方法通常考虑真实GT&#xff08;Ground Truth&#xff09;框与预测框之间的几何关系&#xff0c;通过边界框的相对位置和形状计算损失&#xff0c;但忽略了边界框本身的形状和…

uboot笔记(一):概括/移植等

目录 前言一、下载地址二、目录介绍三、编译四、移植/适配五、启动流程 前言 本笔记以u-boot-2024.10-rc4代码、在arm64平台运行为例对uboot的介绍、编译、适配移植、运行过程的关键流程等&#xff1b; 一、下载地址 https://ftp.denx.de/pub/u-boot/ 下载自己想要使用的版本即…

并发编程三大特性(原子性、可见性、有序性)

并发编程的三大特性实际是JVM规范要求的JVM实现必须保证的三大特性 不同的硬件和不同的操作系统在内存管理上有一定的差异&#xff0c;JAVA为了解决这种差异&#xff0c;使用JMM&#xff08;Java Memry Model&#xff09;来屏蔽各个操作系统之间的差异&#xff0c;使得java可以…

关于malloc,calloc,realloc

1.引用的头文件介绍&#xff1a; 这三个函数需要调用<stdlib.h>这个头文件 2.malloc 2.1 函数简单介绍&#xff1a; 首先这个函数是用于动态开辟一个空间&#xff0c;例如数组在c99标准之前是无法arr[N]的&#xff0c;这个时候就需要使用malloc去进行处理&#xff0c…