常用的字符串与内存操作函数(2)

news2025/1/16 15:04:37

Tips

1. 

2. 

strerror() 

1. C语言的库函数在运行的时候,如果发生错误,就会将错误码存在一个变量里面。这个变量就是:errno(全局变量)。 

2.  这个函数的功能在于把错误码转化为对应的错误信息,错误信息说白了就是一个字符串,它返回错误信息所对应的地址(并不是直接打印出来), 这个函数其实就是你给我传一个数字,我把这个数字对应的错误信息的起始地址给你返回来。

正是因为电脑库函数运行一旦发生错误,计算机就会主动把错误码放到errno这个全局变量里面去,因此strerror的参数往往就是errno

3. 错误码是一些数字,比方说1.2.3.4.....我们需要将错误码翻译成错误信息,其实每一个这样的错误码都对应着一个错误信息

4.  这个函数其实就是你给我传一个数字,我把这个数字对应的错误信息的起始地址给你返回来。

5. 因为错误信息本质上也是一个字符串,所以这个函数就是把错误码对应的错误信息(其实也是一个字符串)首字符的地址给你返回来,所以printf%s直接可以打印出来
6. 实际上当C语言的库函数运行出错误的时候,我们会把错误码放到errno这样一个全局变量里面去,然后你去看这个变量里面的错误码,在翻译成错误信息

7. 比方说要打开一个文件,打开文件在C语言里面用一函数fopen()。我要用这个函数的话,首先得提供一个文件名,在提供一个打开方式。这个函数会返回一个FILE*类型的指针,这个函数如果打开文件成功,就会返回一个有效非空指针;如果打开失败,返回NULL空指针。当我打开文件失败的时候,就很懵逼,到底是什么原因呢?怎么办呢?我就不打印什么“打开文件失败”,我直接用printf%s加上strerror(errno)打印错误信息

8. 用strerror要引用string.h,用errno要用errno.h

9. 你使用errno的前提是前面调用那个函数失败了,它把错误码放进全局变量errno里面去了,这时候你把错误码用strerror转化成错误信息可以看到 

perror() 

1. 还有一个函数perror,它其实是打印错误信息, 是更加直接直接打印错误信息。在打印错误信息之前,你可以自己先传一些自定义信息,它会先打印你给它的信息。

2. perror自己肯定会去捕获errno里面的错误码,然后自己转化为错误信息,直接给你打印出来,当然还可以加上你给的前缀。

3. perror = printf + strerror。

4. 它主动会去找错误信息。但它不管三七二十一直接打印错误信息,但如果我只是为了把错误码转化为错误信息,想获得错误信息的字符串,并不想打印,那么我还得回归到strerror去得到错误信息字符串首地址。 

5. 

字符分类函数 

1. 之前这些都是与字符串相关的函数,而我们现在这些是与字符相关的 

2. 这些is...字符分类函数的设计全都是一样的,如果是,返回一个非0数字,不是的话就返回0。 

参考:

3. 都是需要引用头文件的    ctype.h 

字符转换函数 

1. 还有一种是字符转换函数tolower()与toupper()。注意在上述这些函数里面,字符与ACSII码两者不用太过于纠结,两者是很灵活地可以自由根据情况转化的 

注:这些字符转换函数与位运算一样,都是没有副作用的,产生的只是一个效果,把转换之后的结果给你返回来。自己并不会真正改动它,而且也做不到,因为是值传递嘛 

例: 将单词首字母改成大写的 

#include <ctype.h>
#include <string.h>
int main()
{
	char arr[20] = { 0 };
	gets(arr);
	int sz = strlen(arr);
	if (islower(*arr))
		*arr = toupper(*arr);
	int i = 0;
	for (i = 1; i < sz - 1; i++)
	{
		if (islower(*(arr + i)) && *(arr + i - 1) == ' ')
		{
			*(arr + i) = toupper(*(arr + i));
		}
	}
	printf("%s\n",arr);
}

memcpy()   (内存数据的拷贝)

1. 为什么有了字符串的拷贝之后,还需要内存的拷贝呢?因为字符串的拷贝只针对字符串,而我如果想要两个整型数组拷贝则束手无策。 

2. 拷贝其他东西,那么只能通过内存拷贝函数了。 

3. 你会发现它的参数是void*,为啥呢?因为这个是内存拷贝,你内存条里的数据类型可能是整数(拷贝整型数组),可能是结构体(拷贝结构体数组),可能是浮点数.....为了使得该函数有良好的兼容性,用瞎子垃圾桶void*可以接受任何类型,也正是因为是瞎子void*因为我得指定第三个参数,你要拷贝几个字节得给我传过来。 

4. 
     1. 拷贝多少个字节,你要自己去算的。而且你的目标指针与源头指针得自己看好,想怎么搞就怎么搞
     2. void*接受完后,这个参数指针就是void*了,就是瞎子,但好在你指定了多少个字节拷贝数。
     3. 拷贝多少个字节不一定要凑好,它不挑剔的,这时候就需要涉及到大小端字节序存储了,自己看着办。大小端字节序存储对指针解引用与内存操作函数都可能有影响。 

5. 模拟实现memcpy()

#include <assert.h>
void* my_memcpy(void* dest, const void* src, size_t num)
{
	assert(dest && src);
	void* ret = dest;
	while (num--)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}

注:
1. 参数是void*,无法解引用,需要强制类型转换。这时候你思考的纬度是一个字节/内存单元。而且计算机里面也是以字节为基本单位。强制类型转换为char*这样子你这个指针的势力范围与步长都与基本单位匹配了。
2. 强制类型转换是临时的
3. 返回一个void*指针,回头你要用自己转换成要想的类型 

memmove() (实现源头与目标内存重叠情形下的拷贝)

1. 这边主要是涉及到要拷贝的内存空间与目标内存空间重叠的一个问题,那么这时候该怎么去拷贝呢

2.  总原则:源头指针指向的要拷贝的内容不要被覆盖与破坏

3. 模拟实现memmove() 

#include <assert.h>
void* my_memcpy(void* dest, const void* src, size_t num)
{
	void* ret = dest;
	assert(dest && src);
	while (num--)
	{
		if (src > dest)
		{
			*((char*)dest) = *((char*)src);
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
		else
		{
			*((char*)dest + num) = *((char*)src + num);
		}
	}
	return ret;
}

附: 

memcmp() 

1. 如同strcmp()一样,memcmp也是对应位置一对字节一对字节依次这么去比较 

2. 一个字节其实里面就是八位二进制数,当然可以比较了 

3. 再次说明,大小端字节序存储对于指针解引用操作与内存操作函数都是有影响的 

4. 返回类型与strcmp一个道理 

memset() (内存放置函数)

1. 其实就是将内存设置成我们想要的内容,是以字节为基本单位,以字节为单位来设置内存中的数据的。

2. 返回的是参数指针ptr

3. 

 

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

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

相关文章

macOS 13.2 开发者预览版 Beta2(22D5038i)发布

黑果魏叔 1 月 11 日消息&#xff0c;苹果今日向 Mac 电脑用户推送了 macOS 13.2 开发者预览版 Beta 2 更新&#xff08;内部版本号&#xff1a;22D5038i&#xff09;&#xff0c;本次更新距离上次发布隔了 27 天。macOS Ventura 带来了台前调度、连续互通相机、FaceTime 通话接…

纯CSS输入区域下划线

使用纯CSS实现文本输入的下划线&#xff0c;简洁有效&#xff0c;实现效果&#xff1a; 实现方式 实现方式也很简单&#xff1a; background: linear-gradient(#999 1px, transparent 0) 0 -1px/100% 2em; 例子代码&#xff1a; <!DOCTYPE html> <html lang"e…

【C语言航路】第十站:指针(三)深刻理解指针运算

目录 一、深刻理解指针和数组 1.一维数组 2、字符数组 &#xff08;1&#xff09;字符变量存放到数组中 &#xff08;2&#xff09;字符串存放到字符数组 &#xff08;3&#xff09; 字符串存放到一个指针中 3.二维数组 二、指针与数组经典笔试题 1.题1 2.题2 3.题3…

MCU-51:单片机之红外遥控(外部中断)

目录一、红外遥控简介二、硬件电路三、基本发送与接收四、NEC码五、代码演示5.1 红外遥控5.2 红外遥控电机调速注意&#xff1a;一定要看一、红外遥控简介 红外发射装置 也就是通常我们说的红外遥控器是由键盘电路、红外编码电路、电源电路和红外发射电路组成。红外发射电路的…

爬虫逆向之字体反爬(一)、镀金的天空-字体反爬-1

题目地址&#xff1a;http://www.glidedsky.com/level/crawler-font-puzzle-1 写一下之前处理过的几个字体反爬实战&#xff0c;也是很常见的一种反爬类型&#xff0c;这是第一篇 先来看一下题目 源码拿到的数字&#xff0c;和实际显示在网页的数字&#xff0c;明显不一样的 …

相见恨晚的 IDEA 使用技巧,能让你的代码飞起来

Live Templates 是什么&#xff0c;听上去感觉挺玄乎的。有的同学用过之后觉得简直太好用了&#xff0c;不能说大大提高了开发效率吧&#xff0c;至少也是小小的提高一下&#xff0c;节省了很多敲重复代码的时间。有的同学用过之后说&#xff1a;没什么用&#xff0c;奇技淫巧罢…

C语言_程序环境和预处理

目录 1. 程序的翻译环境 2. 程序的执行环境 3. C语言程序的翻译链接 4. 预编译过程详解 4.1 预定义符号介绍 4.1.1 __FILE__ //进行编译的源文件 4.1.2 __LINE__//文件当前的行号 4.1.3 __DATE__//文件被编译的日期 4.1.4 __TIME__//文件被编译的时间 4.1.5 __STDC__…

基于python的学生信息管理系统

《学生信息管理系统》程序使用说明在IDLE中运行《学生信息管理系统》即可进入如图1所示的系统主界面。在该界面中可以选择要使用功能对应的菜单进行不同的操作。在选择功能菜单时&#xff0c;有两种方法&#xff0c;一种是输入1&#xff0c;另一种是按下键盘上的↑或↓方向键进…

【Javascript】高阶函数,JSON,forEach,map,filter,reduce函数

❤️ Author&#xff1a; 老九 ☕️ 个人博客&#xff1a;老九的CSDN博客 &#x1f64f; 个人名言&#xff1a;不可控之事 乐观面对 &#x1f60d; 系列专栏&#xff1a; 文章目录高阶函数箭头函数apply函数JSONfilter函数map函数总结reduce函数find/findIndex函数every/some函…

线缆行业单绞机控制算法(详细图解)

在了解单绞机之前需要大家对收放卷以及排线控制有一定的了解,不清楚的可以参看下面几篇博客,这里不再赘述,受水平和能力所限,文中难免出现错误和不足之处,诚恳的欢迎大家批评和指正。 收放卷行业开环闭环控制算法 PLC张力控制(开环闭环算法分析)_RXXW_Dor的博客-CSDN博…

知识难懂到什么程度

爱因斯坦相对论&#xff0c;诺贝尔评委会都看不懂&#xff0c;到底说的是什么1905年&#xff0c;爱因斯坦发布狭义相对论&#xff1b;1916年&#xff0c;发布广义相对论&#xff1b;2年后&#xff0c;英国的汤姆逊教授通过实验验证了广义相对论的正确&#xff0c;同时也把爱因期…

容器适配器中stack queue priority_queue的介绍及模拟实现

文章目录容器适配器的概念deque的介绍及底层结构stack的介绍 stack的模拟实现 queue的介绍 queue的模拟实现 priority_queue的介绍 priority_queue的模拟实现 容器适配器的概念 适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验…

清华大佬超全超详细讲解——C++STL看这份教程就够了

2022 年年度编程语言揭榜啦&#xff01;在上个月预想的 C、C、Python 三种候选语言中&#xff0c;C 脱颖而出&#xff0c;成为 TIOBE 2022 年度编程语言的最终获得者&#xff01;新的一波学习热潮要来了。TIOBE 编程语言社区排行榜是编程语言流行趋势的一个指标&#xff0c;每月…

数据分析思维(三)|测试/对比思维

测试/对比思维 1、概念 测试/对比思维可以说在数据分析的工作中随处可见。当我们通过各种手段得到一些结果数据后&#xff0c;如何评价结果的好坏呢&#xff1f;这个时候你可能会想到和标准结果进行比较、和之前的数据进行对照等等方法&#xff0c;这些方法归根结底就是一种测…

ubuntu 安装 Gitkraken 8.1.1 Pro 版本

GitKraken 是一个非常好用的 Git 图形界面客户端, 自 6.5.1 版本以后, GitKraken 对私有仓库不再免费开放使用 本文介绍一个 ubuntu 安装 GitKraken 8.1.1 Pro 版本的方法 环境准备 安装 yarn 测试过 node 18.12.1 版本, 没能升级到 Pro 版, 可能是因为 GitCracken 仓库太久…

springboot+sa-token-quick-login实现快速登录

当你的项目需要一个登录认证功能&#xff0c;这个登录界面可以不华丽、可以烂&#xff0c;但是一定要有&#xff0c;同时你又不想花费太多的时间浪费在登录页面上&#xff0c; 那么你便可以尝试一下Sa-Token-Quick-Login。 1、Sa-Token-Quick-Login Sa-Token-Quick-Login 可以…

5.4、TCP 流量控制(滑动窗口机制)

一般来说&#xff0c;我们总是希望数据传输得更快一些。 但如果发送方把数据发送得过快&#xff0c;接收方就可能来不及接收&#xff0c;这就会造成数据的丢失。 所谓流量控制(flow control)就是让发送方的发送速率不要太快&#xff0c;要让接收方来得及接收\color{red}让发送…

基于微信小程序的个人健康数据管理系统小程序

文末联系获取源码 开发语言&#xff1a;Java 框架&#xff1a;ssm JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7/8.0 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.3.9 浏览器…

第一章.机器学习的前期准备—jupyter 更换文件路径的方法,jupyter使用方法,训练/验证/测试数据集的概念,学习方式,常见应用

第一章.机器学习的前期准备 1.1 第一章.机器学习的前期准备 1.jupyter软件的安装 说明:可以使用Anaconda软件中的jupyter软件 1).jupyter 更换文件路径的方法&#xff1a; ①.查找电脑中是否存在 jupyter_notebook_config.py 文件&#xff0c;若不存在&#xff0c;通过命令提…

前端最基础面试题:说说JavaScript中如何判断数据类型?

1. 基本数据类型的判定&#xff1a;typeof [变量名] typeof 1 // number typeof string呀 // string typeof true // boolean typeof Symbol(abc) // symbol控制台验证&#xff1a; 2. 引用类型 object 的判断&#xff1a; ① constructor ② instanceof ③ Object.prototy…