C语言字符串函数库全解!一篇文章大彻大悟醍醐灌顶!

目录

1.字符分类函数

2.字符转换函数

3.strlen的使用和模拟实现

4.strcpy的使用和模拟实现

5.strcat的使用和模拟实现

6.strcmp的使用方法及模拟实现

7.strncpy函数的使用与模拟实现

8.strncat函数的使用方法以及模拟实现

9.strncmp函数的介绍

10.strstr的使用和模拟实现


1.字符分类函数

C语言中有一系列的函数是用来做字符分类的,也就是一个字符是属于什么类型的字符的。

这些函数的使用都需要包含的一个头文件是<ctype.h>

下图就是这些函数

他们的返回值是int,而且只具有一个参数,而且他们的使用方法极其相似,我们只讲解其中一个函数即可大彻大悟一通百通。

int islower (int c)

 这个函数是用来判断参数是否为小写字母的,如果是小写字母的话就会返回一个非0的值,不是小写字母的话就会返回0.如下图所示

现在我们进行一个练习:

写一个代码,将字符串中的小写字母转大写,其他字符不变。

我们刚刚已经知道了islower的运用方法,我们只需要使用islower判断出字符串的小写字母,然后让这个字符减去32即可得到大写字母。

2.字符转换函数

C语言库中提供了两个字符转换函数

	int tolower(int c);//将参数传进去的大写字母转小写.int toupper(int c);//将参数传进去的小写字母转大写.

有了这两个函数,我们就可以不通过ASCII码的计算来完成小写字符转大写字符,直接使用这个函数即可。

#include <stdio.h>
#include <ctype.h>
int main()
{char arr[] = "kuku";for (int i = 0; arr[i] != '\0'; i++){if (islower(arr[i])){//arr[i] -= 32;arr[i]=toupper(arr[i]);putchar(arr[i]);}}return 0;
}

3.strlen的使用和模拟实现

这个函数是用来求字符串长度的

函数原型如下 

size_t strlen(const char* str)

1.这串代码返回的是字符串'\0'之前的字符个数

2.参数指向的字符串必须要以‘\0’结尾

3.函数的返回值是size_t,是无符号的。

4.strlen的使用需要包含<string.h>头文件

现在我们使用strlen函数来比较一下两个字符串的长度

#include <stdio.h>
#include <string.h>
int main()
{const char* str1 = "asdfadfgsfxcvbstrfg";const char* str2 = "nihaoyawoshikuku";if (strlen(str1) - strlen(str2) > 0){printf("字符串1长");}else{printf("字符串2长");}return 0;
}

输出结果:字符串1长 

下面我们来模拟实现一下strlen函数

#include <stdio.h>
#include<assert.h>
//计数器的方式
int strlen1(const char* str)
{int count = 0;assert(str);while (*str){str++;count++;}return count;
}
//递归方式
int strlen2(const char* str)
{assert(str);if (*str == '\0'){return 0;}else{return 1 + strlen2(str+1);}
}
//指针运算方式
int strlen3(const char* str)
{assert(str);char* p = str;while (*p!='\0'){p++;}return p - str;
}
int main()
{const char *str = "asdfg\0";int a = strlen1(str);int b = strlen2(str);int c = strlen3(str);printf("a=%d\nb=%d\nc=%d", a, b, c);return 0;
}

4.strcpy的使用和模拟实现

	char* strcpy(char* destination, const char* source);//功能是把第二个参数从第一个参数的第一个字符位置复制到第一个字符串中

1.源字符串必须以'\0'结尾

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

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

4.目标空间必须可修改-->不能被static和const修饰 

 它的实现非常简单,现在我们来实现一下

char strcpy(char* dest, const char* src)
{assert(dest);assert(src);char* ret = dest;//版本1while (*dest){*dest = *src;dest++;src++;}//第一步优化while (*dest){*dest++ = *src++;}//第二布优化while (*dest++ = *src++)//虽然是写在判断条件内部,但由于是指针操作//所以操作结果可以保存在内存中{;}return ret;
}

5.strcat的使用和模拟实现

函数原型如下:

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

它的作用是在字符串的末尾追加字符。

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

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

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

4.目标空间必须可修改。

5.无法使用这个函数给自己追加。

现在模拟实现一下这个函数:

char* strcat(char* dest, const char* src)
{assert(dest);assert(src);char* p = dest;while (*dest){dest++;}while (*dest++ = *src++){;}return p;
}

6.strcmp的使用方法及模拟实现

strcmp() 函数是C语言中用于比较两个字符串的函数。它会逐个字符比较两个字符串,直到遇到不同的字符或者其中一个字符串的结束符 \0

具体来说,strcmp() 函数的作用是:

  1. 如果两个字符串相等,返回值为0。
  2. 如果第一个字符串小于第二个字符串,返回值为负数。
  3. 如果第一个字符串大于第二个字符串,返回值为正数。

这里再给大家详细解释一下字符串的比较。

我们知道的是,在比较数字时,我们会先比较高位,再比较低位。

我们比较字符串运用的就是这个原理!从高位向低位比较ASCII码的值。

那么现在我们来实现一下这个函数。

int strcmp(const char* str1, const char* str2)
{int ret = 0;while (*str1 == *str2){if (*str1 == '\0')//如果str1和str2都等于\0,会进入循环内。//if语句用来判断这个。{return 0;}str1++;str2++;}return *str1 - *str2;
}

7.strncpy函数的使用与模拟实现

这个函数的原型如下

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

strncpy函数是一个字符串拷贝函数,它可以拷贝num个字符从源字符串到目标空间。

1.目标空间和源空间不可重叠,若重叠则需要使用内存拷贝函数。后续会介绍给大家

2.如果源字符串的长度小于num,则在拷贝完源字符串后,在目标的后面追加0,直到num个。

现在我们来模拟实现一下这个函数

//实现方法1
char* strncpy1(char* destination, const char* source, size_t num)
{char* ret = destination;while (*source&&num){*destination++ = *source++;num--;}while (num > 0){*destination++ ='0';num--;}return ret;
}
//实现方法2
char* strncpy2(char* destination, const char* source, size_t num)
{int i = 0;char* ret = destination;while (*source && num){*destination++ = *source++;num--;}while (num){*destination++ ='0';num--;}return ret;
}

//实现方法3
char* strncpy3(char* destination, const char* source, size_t num)
{int i;for (i = 0; src[i] && i < n; i++){destination[i] = src[i];}if (i < n){dst[i] = 0;}return dst;
}

8.strncat函数的使用方法以及模拟实现

函数原型如下:

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

1.strncat是一个字符串追加函数,可以将这个函数指向的source字符串的前num个字符追加       到destination指向的字符串末尾,再追加一个‘\0’.

2.如果source指向的字符串长度小于num,则只会将字符串到\0的内容追加到destination的末尾。

现在我们来模拟实现一下这个函数。

#include <stdio.h>
#include <assert.h>
char* strncat(char* dest, const char* src,size_t n)
{assert(dest);assert(src);char* ret = dest;while (*dest){dest++;}while (*src&&n){*dest++ = *src++;n--;}*dest = '\0';return ret;
}
int main() {char dest[100]="bendan";const char* src = "Hello";char* result1 = strncat(dest, src, 8);char* result2 = strncat(dest, src, 3);printf("%s\n", result1);printf("%s\n", result2);return 

 相信大家经过实现这些函数已经发现了这类函数的实现方法,下面的函数将不再模拟实现。

9.strncmp函数的介绍

这个是一个字符串比较函数,但是只比较num个字符。

函数原型如下:

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

这个函数是比较str1和str2的前num个字符,如果相等就继续向后比较,一直比较到第num个字符。

10.strstr的使用和模拟实现

这个函数超级重要!!!

strstr函数是一个字符串查找函数,它的函数原型如下;

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

1.这个函数的作用是查找并返回字符串str2在字符串str1中第一次出现的地址(指针)

2.如果str2不在str1中,则返回空指针

3.字符串的⽐较匹配不包含 \0 字符,以 \0 作为结束标志

我们先来使用一下他!

这段代码的功能是先找到simple在str中出现的位置,然后返回第一次出现的地址,之后再使用字符串拷贝函数,将i替换为a.

现在我们来模拟实现一下这个函数

char* my_strstr(const char* str1, const char* str2)
{char* cp =str1;char* s1,*s2;if (!*str2)//如果为空,则为真,则进入语句块。{return str1;}while (*cp){s1 = cp;s2 = str2;while (*s1 && *s2 && !(*s1 - *s2)){s1++;s2++;}if (!*s2){return cp;}cp++;}
return NULL;
}
int main()
{char str[] = "This is a simple string";char* pch;pch = my_strstr(str, "simple");//注意这个函数的返回值printf("%s\n", pch);strncpy(pch, "sample", 10);printf("%s\n", pch);return 0;
}

在这里说以下这个函数的实现思路。

首先,str2为空时,我们应直接返回str1。

其次,我们每次比较完都要让str1走一步,因此需要定义一个指针cp来一步步的走。而且,这个指针不能在循环内部有+1之外的操作。因此我们比较还需要定义一个指针s1等于cp。

之后,每次比较完毕后,若不符合条件,则str2需要回到初始地址。所以我们需要定义两个指针来表示str1和str2.

最后,如果在比较的过程中,我们发现在str1中找到了str2,就可以返回cp的地址了。

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

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

相关文章

springboot整合mybatis-puls登陆注册

目录 创建springboot项目 目录结构&#xff1a; 启动类 测试类 idea建表 pom文件 编写yml文件 qq邮箱设置 登陆注册代码 编写持久层(Dao) 注册代码 业务层 业务实现类 mapper 控制层 前端代码 注册页面 邮件正文&#xff1a; 登录代码 控制层 业务层&#…

前端开发攻略---实现发送手机验证码60s倒计时效果(手机号验证+按钮文字自定义显示+Vue2写法+Vue3写法)

1、演示 2、说明 1、为了便于演示&#xff0c;本示例将在3秒后就再次发送。您可以根据需要自定义此时间间隔。 2、采用最少的变量以满足需求&#xff0c;以减少内存占用。 3、不仅仅局限于按钮情况&#xff0c;也可应用于不禁用按钮的情况&#xff0c;以实现更多的扩展性。 4、…

FPGA组合逻辑电路设计之译码器

在数字电路中可以根据电路功能的不同分为&#xff0c;组合逻辑电路与时序逻辑电路。组合逻辑 电路在逻辑功能上的特点是任意时刻的输出仅仅取决于该时刻的输入&#xff0c;与电路原来的状态无 关。而时序逻辑从电路特征上看来&#xff0c;其特点为任意时刻的输出不仅取决于该…

安卓NetworkStatsManager使用及demo

目录 一、TrafficStats类简介二、demo示例 一、TrafficStats类简介 TrafficStats Android API 8提供了android.net.TrafficStats类。 通过此类能获取设备重启以来网络信息&#xff0c;部分函数如下所示&#xff1a; static long getMobileRxBytes() //获取通过移动数据网络…

【SpringBoot】-MyBatis详解+单表操作

作者&#xff1a;学Java的冬瓜 博客主页&#xff1a;☀冬瓜的主页&#x1f319; 专栏&#xff1a;【Framework】 主要内容&#xff1a;什么是MyBatis框架&#xff1f;MyBatis框架有什么用&#xff1f;MyBatis实现查询步骤详解。MyBatis实现单表的增删查改。MyBatis模糊查询&…

TDSQL手动调整备份节点或冷备节点

一、背景描述 近期TDSQL数据库备份不稳定&#xff0c;有些set实例的备份任务未自动发起。经排查分析&#xff0c;存在多个set实例容量已经超过TB级别&#xff0c;且冷备节点都是同一台。因此&#xff0c;需要手动将当前备份节点改到其他备节点&#xff0c;开启增量备份&#x…

FLStudio怎么冻结轨道以及如何批量复制音符

FLStudio是一款功能强大的音乐制作软件&#xff0c;广泛用于音乐制作和打谱当中。我们在制作音乐时&#xff0c;经常会遇到处理大量音频轨道的情况&#xff0c;过多的音频轨道可能会导致电脑性能受限&#xff0c;从而影响工作流程。为了应对这个问题&#xff0c;FLStudio提供了…

CPPTest实例分析(C++ Test)

1 概述 CppTest是一个可移植、功能强大但简单的单元测试框架&#xff0c;用于处理C中的自动化测试。重点在于可用性和可扩展性。支持多种输出格式&#xff0c;并且可以轻松添加新的输出格式。 CppTest下载地址&#xff1a;下载地址1  下载地址2 下面结合实例分析下CppTest如…

小样本学习登Nature!计算效率高170倍,彻底起飞

中科院新提出的社会行为图谱SBeA登上Nature子刊&#xff01; SBeA是一个用于多动物3D姿势估计、身份识别和社会行为分类的小样本学习框架&#xff0c;能够全面量化自由群居动物的行为&#xff0c;使用较少的标记帧数&#xff08;约 400 帧&#xff09;进行多动物三维姿态估计。…

linux常用非基础命令/操作

本篇用于总结蒟蒻博主在使用linux系统的过程中会经常用到但老实记不住的一些非基础命令和操作&#xff0c;方便遗忘时查阅 一&#xff0c;关闭指定端口的进程以释放端口 每个端口都有一个守护进程&#xff0c;kill掉这个守护进程就可以释放端口 ①使用命令【netstat -anp | gre…

数据结构|树形结构|并查集

数据结构|并查集 并查集 心有猛虎&#xff0c;细嗅蔷薇。你好朋友&#xff0c;这里是锅巴的C\C学习笔记&#xff0c;常言道&#xff0c;不积跬步无以至千里&#xff0c;希望有朝一日我们积累的滴水可以击穿顽石。 有趣的并查集剧情演绎&#xff1a;【算法与数据结构】—— 并…

045、seq2seq

之——序列生成 杂谈 基于RNN实现&#xff0c;通过RNN生成器不断获取输入&#xff0c;更新隐藏状态&#xff0c;将最后生成的隐藏状态传递给解码器&#xff0c;然后自循环迭代直到输出停止。 正文 1.训练 训练时候解码器使用目标句子不断作为输入&#xff0c;就算解码错了输入…

linux休眠唤醒流程,及示例分析

休眠流程 应用层通过echo mem > /sys/power/state写入休眠状态&#xff0c;给一张大概流程图 这个操作对应在kernel/power/main.c的state这个attr的store操作 static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,const char *buf, size_t n) …

ESP32-Thonny 拍摄图片到SD卡

前言&#xff1a; 代码运行在Thonny 添加main.py到单片机中&#xff1a; 可以先运行一下试试&#xff1a;会输出以下信息&#xff1a; 没有问题的话&#xff08;SD卡挂载成功&#xff0c;摄像头初始化成功&#xff09;运行一次主程序后&#xff0c;闪光灯会闪烁一下。 代码&…

js获取某月往前推一年或半年的年月数组

前言 需求&#xff1a;需要显示某月份往前推一年或者半年的费用情况&#xff0c;显示到柱形图上&#xff0c;后台接口只返回有数据的年份&#xff0c;这就需要前端拿全部月份数组去比对并显示。 开始 上代码&#xff1a; // date:选择的月份,比如:2024-04,//n:半年或者1年,…

PTA 天梯赛 L1-010 比较大小【C++】 L1-011 A-B 【C++ vector动态数组】【Python 字符串replace函数】

L1-010 比较大小 判断顺序很重要 #include<iostream> using namespace std; int main() {int a, b, c;cin >> a >> b >> c;int temp;if (a > b) {temp a;a b;b temp;}if (a > c) {temp a;a c;c temp;}if (b > c) {temp b;b c;c te…

C++ //练习 13.17 分别编写前三题中所描述的numbered和f,验证你是否正确预测了输出结果。

C Primer&#xff08;第5版&#xff09; 练习 13.17 练习 13.17 分别编写前三题中所描述的numbered和f&#xff0c;验证你是否正确预测了输出结果。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 /*************************…

【御控物联网平台】物联网平台常见通讯协议

随着物联网&#xff08;InternetofThings&#xff0c;IoT&#xff09;的快速发展&#xff0c;越来越多的设备和传感器连接到网络&#xff0c;使得数据的传递和交互变得更加智能化和高效化。在实现这种智能化和高效化的数据交互&#xff0c;过程中&#xff0c;各种不同的通信协议…

防火墙技术基础篇:什么是防火墙

防火墙技术基础篇&#xff1a;什么是防火墙 什么是防火墙&#xff1f; 在我们开始之前&#xff0c;让我们先想象一下一个真实的场景。你的家是你的私人领地&#xff0c;你不希望任何未经许可的人进入。为了保护你的家&#xff0c;你可能会安装一些安全设备&#xff0c;比如门…

webpack中mode、NODE_ENV、DefinePlugin、cross-env的使用

本文讲的全部知识点&#xff0c;都是和webpack相关的。如果你之前有疑问&#xff0c;那本文一定能帮你搞清楚。 问题来源一般是类似下面代码&#xff08;webpack.json中&#xff09;&#xff1a; "scripts": {"dev": "cross-env NODE_ENVdevelopmen…