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函数就可以将错误对应的错误信息字符串的地址返回。

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

如何用人工智能实现客户服务营销?实用指南与关键技巧一网打尽

在不断发展的营销领域&#xff0c;创意是成功营销活动的生命线。火花点燃兴趣&#xff0c;吸引受众&#xff0c;推动参与。但是&#xff0c;如果有一种方法可以利用技术来提升创意&#xff0c;那会怎样呢&#xff1f;生成式人工智能&#xff08;Generative AI&#xff09;是一种…

数据结构与算法----复习Part 16 (并查集)

本系列是算法通关手册LeeCode的学习笔记 算法通关手册&#xff08;LeetCode&#xff09; | 算法通关手册&#xff08;LeetCode&#xff09; (itcharge.cn) 目录 并查集&#xff08;Union Find&#xff09; 基于数组实现的快速查询并查集 基于森林实现的快速合并并查集 路径…

51单片机-AT24C02(I2C总线)

目录 一&#xff0c;介绍及元件工作原理 7.时序结构&#xff08;重要&#xff09; 8.i2C总线数据帧&#xff08;重要&#xff09; 二&#xff0c;应用 一&#xff0c;介绍及元件工作原理 1.元件介绍 2.存储器 3.地址总线和数据总线 地址总线只能一次选中一行 4.引脚及应用…

三次握手seq和ack的流程 TCP协议栈seq和ack深层理解

☆ 大家可以把想了解的问题在评论发给我?我会根据问题补充到后面 ☆ 三次握手seq和ack的流程 是的,在TCP/IP协议中,三次握手过程确实涉及到序列号(Sequence Number, 简称Seq)和确认号(Acknowledgment Number, 简称Ack)的交换。这个过程是为了建立可靠的连接,确保数据能…

Python基础(七)之数值类型字典

Python基础&#xff08;七&#xff09;之数值类型字典 1、简介 字典&#xff08;dict&#xff09;&#xff0c;Dictionary:是一种可变类型&#xff0c;可以存储任意类型的元素&#xff0c;如列表、字符串、元组等。 字典是无序的&#xff0c;所以不支持索引和切片。字典以键值…

CSS中如何设置单行或多行内容超出后,显示省略号

1. 设置超出显示省略号 css设置超出显示省略号可分两种情况&#xff1a; 单行文本溢出显示省略号…多行文本溢出显示省略号… 但使用的核心代码是一样的&#xff1a;需要先使用 overflow:hidden;来把超出的部分隐藏&#xff0c;然后使用text-overflow:ellipsis;当文本超出时…

软考 系统架构设计师之回归及知识点回顾(7)

接前一篇文章&#xff1a;软考 系统架构设计师之回归及知识点回顾&#xff08;6&#xff09; 11. 云计算 背景 大数据和云计算已成为IT领域的两种主流技术。“数据是重要资产”这一概念已成为大家的共识&#xff0c;众多公司争相分析、挖掘大数据背后的重要财富。同时学术界、…

哔哩哔哩后端Java一面

前言 作者&#xff1a;晓宜 个人简介&#xff1a;互联网大厂Java准入职&#xff0c;阿里云专家博主&#xff0c;csdn后端优质创作者&#xff0c;算法爱好者 最近各大公司的春招和实习招聘都开始了&#xff0c;这里分享下去年面试B站的的一些问题&#xff0c;希望对大家有所帮助…

第十二届蓝桥杯EDA省赛真题分析

前言&#xff1a; 第十二届蓝桥杯EDA比赛用的是AD软件&#xff0c;从第十四届起都是使用嘉立创EDA专业版&#xff0c;所以在这里我用嘉立创EDA专业版实现题目要求。 一、省赛第一套真题题目 主观题整套题目如下&#xff1a; 试题一&#xff1a;库文件设计&#xff08;5分&am…

VS Code 配置类似浏览器中的垂直标签页功能

参考&#xff1a;Dominik Weber - 2022.06.25 (注&#xff1a;原文中的配置有些过时了&#xff0c;所以根据 VS Code 的最新版本进行了调整。) 原作者非常喜欢垂直标签页&#xff0c;只要有可能&#xff0c;就都会使用它们。他主要在浏览器&#xff08;Firefox&#xff09;和…

Python之Web开发中级教程----ubuntu中下载安装Postman

Python之Web开发中级教程----ubuntu中下载安装Postman PostMan 是一款功能强大的网页调试与发送网页 HTTP 请求的 Chrome 插件&#xff0c;可以直接去对我们写出来的路由和视图函数进行调试&#xff0c;作为后端程序员是必须要知道的一个工具。 查看ubuntu系统中是否已经安装了…

VsCode 配置go开发环境之下载go tools

ctrl shift P 选择 go install/update tools&#xff0c;下载go tools 报错&#xff0c; 提升dial err。 将GOPROXY 和 GOSUMDB 按照如下配置&#xff0c;重启IDE即可成功下载 set GOPROXYhttps://goproxy.cn set GOSUMDBoff

程序人生——Java多线程和并发的使用建议

目录 引出多线程和并发建议118&#xff1a;不推荐覆写start方法建议119&#xff1a;启动线程前stop方法是不可靠的建议120&#xff1a;不适用stop方法停止线程 建议121&#xff1a;线程优先级只使用三个等级建议122&#xff1a;使用线程异常处理器提升系统可靠性建议123&#x…

【递归专题】【蓝桥杯备考训练】:有序分数、正则问题、带分数、约数之和、分形之城【已更新完成】

目录 1、有序分数&#xff08;usaco training 2.1&#xff09; 2、正则问题&#xff08;第八届蓝桥杯省赛C A组 & Java A组&#xff09; 3、带分数&#xff08;第四届蓝桥杯省赛Java A组/B组 & C B组/C组&#xff09; 4、约数之和&#xff08;《算法竞赛进阶指南》…

jvm的垃圾回收器以及触发full gc的场景

JVM&#xff08;Java虚拟机&#xff09;的垃圾回收器有很多种&#xff0c;主要包括以下几种&#xff1a; Serial收集器&#xff1a;串行收集器是最古老、最稳定的收集器。它使用单个线程进行垃圾收集工作&#xff0c;在进行垃圾回收时会暂停所有用户线程。 ParNew收集器&#…

ViT如何支持变长序列输入?

当增加输入图像的分辨率时&#xff0c;例如DeiT 从 224 到 384&#xff0c;一般来说会保持 patch size&#xff08;例如9&#xff09;&#xff0c;因此 patch 的数量 N 会发生了变化。那么视觉transformer是如何处理变长序列输入的? DEiT中如何处理mask数据的&#xff1f; 例…

智慧公厕对于智慧城市管理的意义

近年来&#xff0c;智慧城市的概念不断被提及&#xff0c;而智慧公厕作为智慧城市管理的重要组成部分&#xff0c;其在监测、管理和养护方面发挥着重要的作用。智慧公厕不仅是城市市容提升的重要保障&#xff0c;还能提升城市环境卫生管理的质量&#xff0c;并有效助力创造清洁…

5_相机标定2_calibrateCamera()与内外参

彩色角点图片镇楼 opencv官方文档&#xff1a; https://docs.opencv.org/4.8.0/d4/d94/tutorial_camera_calibration.html https://docs.opencv.org/3.4.18/d9/d0c/group__calib3d.html#gaebfc1c9f7434196a374c382abf43439b 相机标定目的&#xff1a; cv::calibrateCamera()的…

Arthas使用案例(二)

说明&#xff1a;记录一次使用Arthas排查测试环境正在运行的项目BUG&#xff1b; 场景 有一个定时任务&#xff0c;该定时任务是定时去拉取某FTP服务器上的文件&#xff0c;进行备份、读取、解析等一系列操作。 而现在&#xff0c;因为开发环境是Windows&#xff0c; 线上项…

SpringBoot(数据库操作 + druid监控功能)

文章目录 1.JDBC HikariDataSource&#xff08;SpringBoot2默认数据源&#xff09;1.数据库表设计2.引入依赖 pom.xml3.配置数据源参数 application.yml4.编写一个bean&#xff0c;映射表5.编写测试类来完成测试1.引入依赖 pom.xml2.使用JdbcTemplate进行测试3.成功&#xff0…