字符函数、字符串函数和内存函数

news2024/11/28 1:30:22

朋友们,今天追秋给大家带来的是一些函数的介绍,包括字符函数、字符串函数和内存函数。

字符串函数

字符串函数分为以下几类:
1.长度不受限制的字符串函数:strlen;strcpy;strcat;strcmp;
2.长度受限制的字符串函数:strncpy;strncat;strncmp.

3.还有一些特殊用法的字符串:strstr;strtok;strerror;
下面给大家逐一介绍这些字符串函数:

strlen

size_t strlen (const chatr str)*

使用规则:
1.我们知道字符串是以\0作为结束表示,而strlen函数统计的就是字符串\0之前的字符个数;
2.该函数的返回类型是 size_t 类型,是无符号整形,注意:无符号整形进行运算时不会出现负数的情况出现;
3.该函数的参数类型必须以\0结尾;

例题:

#include <string.h>
int main()
{
	const char* p1 = "abcd";
	const char* p2 = "abcdefg";
	if (strlen(p1) - strlen(p2) >= 0)
		printf(">=\n");
	else
		printf("<\n");
	return 0;
}

运行结果:
在这里插入图片描述
由此可见,同样的整形数据运行结果为负数的时候,无符号整形运行结果为负数,这也是整个函数使用时需要注意的地方。

strcpy

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

使用规则
1.源字符串必须以\0结尾;
2.会将源字符串中的\0也拷贝到目标字符串当中;
3.目标空间必须足够大,确保可以将源字符串全部拷贝到目标空间当中;
4.目标空间必须可变;

举例:

源字符串没有以\0结尾

int main()
{
	char arr1[20] = { 0 };
	char arr2[] = { 'a','b','c' };
	strcpy(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

当源字符串中没有\0结尾时,依然进行拷贝,此时程序崩溃:
在这里插入图片描述

目标空间足够大,且将源字符串空间\0进行拷贝

int main()
{
	char arr1[20] = "xxxxxxxxx";
	char arr2[] = { 'a','b','c' ,'\0'};
	strcpy(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

在这里插入图片描述

目标空间无法修改

int main()
{
	char* p = "abcdefg";
	char arr[] = { 'a','b','c','\0' };
	strcpy(p, arr);
	printf("%s\n", p);
	return 0;
}

指针p指向的是常量字符串,而常量字符串是无法修改的,即:目标空间无法修改,程序报错;
在这里插入图片描述

strcat

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

使用规则
1.源字符串必须以\0结尾;
2.会将源字符串中的\0拷贝到目标空间中;
3.目标空间必须可变;

拷贝字符串

int main()
{
	char arr1[20] = "abcd\0xxxxxxx";
	char arr2[] = "efg";
	strcat(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

运行结果:
可以看到,该函数将源字符串空间中的\0也拷贝到了目标字符串空间,同时覆盖掉原本的数据,
在这里插入图片描述

拷贝自身

可以看到,在编译器VS2019上对字符串自身进行拷贝的时候,编译器报错,
但是注意,该函数对自身进行拷贝功能,C语言标准并未定义,该函数是否可以拷贝自身是由编译器自身决定的,根据使用的编译器的不同会出现不同的效果
在这里插入图片描述

strcmp

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

使用规则:
第一个字符串大于、等于、小于第二个字符串时,返回大于0、等于0、小于0的数字;
2.返回类型为int型;

举例:
在这里插入图片描述

strncpy

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

使用规则:
1.从源字符串空间拷贝num的字符到目标空间中;
2.如果源字符串长度小于num,则拷贝完源字符串后,在目标空间后面追加0,直到num个;
注:该函数的使用规则和strcpy的使用规则完全一样,仅仅是多了一个参数的限制,该参数的类型是size_t类型,作用是限制该函数的使用次数,对于strcpy函数的使用基础上进行进一步的细化提升。

举例:

int main()
{
	char arr1[20] = "xxxxxxxxxxxx";
	char arr2[] = "abcd";
	strncpy(arr1, arr2, 6);
	printf("%s\n", arr1);
	return 0;
}

运行结果:
可以看到:当源字符串大小不足时,该函数会自动给目标空间补齐\0,直到num个;
在这里插入图片描述
注:而当大小足够时,不会再字符串后面自动追加\0;
在这里插入图片描述

strncat

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

该函数和strncat类似,功能和strcat一样,只是在功能上更加细化;
举例:

int main()
{
	char arr1[20] = "123\0xxxxxxx";
	char arr2[] = "abcd";
	strncat(arr1, arr2, 3);
	printf("%s\n", arr1);
	return 0;
}

运行结果:
可以看到:在进行字符串追加的时候,在源字符串空间足够的情况下,将字符串拷贝结束之后会追加一个\0在目标空间的末尾;
即:strncat在追加字符串的时候会在字符串的末尾给到一个\0,或者更多的\0;而strncpy只有在源字符串空间不足的情况下才会追加\0.
在这里插入图片描述
而当源字符串空间不足时,该函数依然将源字符串拷贝到目标空间,但拷贝完源字符串时就立即结束,不在进行多余的操作;
在这里插入图片描述

strncmp

这个函数在功能上与strcmp的区别就是比较长度的限制,参数部分多了一个用于限制比较次数的参数;

举例:
在这里插入图片描述
在这里插入图片描述

strstr

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

功能:在字符串str1中查找字符串str2;如果找到了,就返回str1中str2首次出现的位置;如果没找到,就返回NULL(空指针);
注:该库函数返回的是地址;且不可被修改;

举例:
场景一:能找到字符串str2;在这里插入图片描述
场景二:找不到字符串str2;
在这里插入图片描述
场景三:需要查找的字符串str2为空:
可以看到:当需要查找的字符串中没有字符,仅有一个\0时,返回的是被查找字符串str1的起始地址;
在这里插入图片描述
场景四:被查找字符串str1是空字符串;
在这里插入图片描述

strtok

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

使用规则:
1.sep参数是个字符串,定义了用作分隔符的字符集合
2.第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
3.strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
4.strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
5.strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
6.如果字符串中不存在更多的标记,则返回 NULL 指针.

举例:在这里插入图片描述
我们可以看到,此代码虽然可以实现字符串切割的目的,但是实际作用局限性比较大,实现起来也很复杂,我们可以改进以下这个代码:
在这里插入图片描述

strerror

char * strerror ( int errnum );

功能:返回错误码,所对应的错误信息。

举例:
打印部分错误码:在这里插入图片描述

字符函数

字符分类函数

函数 如果他的参数符合下列条件就返回真
iscntrl 任何控制字符
isspace 空白字符:空格‘ ’,换页‘\f’,换行’\n’,回车‘\r’,制表符’\t’或者垂直制表符’\v’
isdigit 十进制数字 0~9
isxdigit 十六进制数字,包括所有十进制数字,小写字母af,大写字母AF
islower 小写字母a~z
isupper 大写字母A~Z
isalpha 字母az或AZ
isalnum 字母或者数字,az,AZ,0~9
ispunct 标点符号,任何不属于数字或者字母的图形字符(可打印)
isgraph 任何图形字符
isprint 任何可打印字符,包括图形字符和空白字符

字符转换函数

int tolower ( int c ); 作用:大写转小写
int toupper ( int c ); 作用:小写转大写

注:传递参数是字母,但是在其中运算是通过ASCII码值运算的,因此参数部分是整形;
这两个函数的返回值为整形,因此要用整形数据来接收,传递的是ASCII码值;

内存函数

我们直到,在计算机在进行数据存储的时候,不仅仅是存储字符型的数据,还要存储其它类型的数据,比如整形,长整型,短整型等一些数据类型。当然,这些数据类型也有相对于的函数来进行拷贝、复制等操作。下面我们来介绍以下这些函数

memcpy

作用:和strcpy类似,只是拷贝的数据类型包括但不限制于字符型数据,可以拷贝其它任意类型的数据。

举例:

int main()
{
	int arr1[10] = { 0 };
	int arr2[] = { 1,2,3,4,5,6,7,8,9,10 };
	memcpy(arr1, arr2, 5 * sizeof(int));
	return 0;
}

运行结果:
在这里插入图片描述
当然这里的字符型数据的例子也是给到大家:
在这里插入图片描述

memmove

作用:和memcpy基本一致,在函数memcpy的基础上增加了一个功能:自己拷贝自己的数据;

举例:

#include <string.h>
int main()
{
	int arr[20] = { 1,2,3,4,5,6,7,8,9,10 };
	memmove(arr+2, arr, 5 * sizeof(int));
	return 0;
}

在这里插入图片描述
注:对于内存函数memcpy和memmove的功能,标准规定:memmove可以对内存空间重叠的数据进行拷贝,memcpy只对内存空间不重叠的数据进行拷贝,而在编译器上是不进行强制要求的,也就是说:在不同的编译器上memcpy的功能可能有所差异,也就是是否可以拷贝内存空间重叠的数据。

memset

功能:此函数为内存设置函数,是以字节为单位来将目标空间设置为特定值;

举例:

int main()
{
	char arr[10] = "abcdefg";
	memset(arr, 'x', 6);
	printf("%s\n", arr);
	return 0;
}

运行结果:
在这里插入图片描述
但是当遇到整形数据等等这些单位长度大于1字节的数据类型的数据时,这个函数的功能就不太方便去重置目标空间的的值;
例如:我们想要将整形数组中的前五个数据改成0;

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	memset(arr, 1, 5*sizeof(int));
	for (int i = 0; i < 10; i++)
	{
		printf("%d\n", arr[i]);
	}
	return 0;
}

运行结果:
在这里插入图片描述
因为是以字节为单位,而整形数据是有四个字节,拿第一个数据举例,设置结束后数据以16进制形式呈现:01010101,即16843009,实际结果和我们的预期结果相差甚远;因此在使用该函数的时候要小心谨慎使用!

memcmp

功能:
1.和函数strcmp类似,但是作用范围更大,可以比较任意类型的数据的大小。
2.结果为大于、等于、小于的时候,返回值给到的是大于0、等于0、小于0的数据,用整形来接收。
3.比较的单位是字节

举例:

int main()
{
	int arr1[] = { 1,2,3,4,5,6 };
	int arr2[] = { 1,2,3,4,6 };
	int ret = memcmp(arr1, arr2, 4 * sizeof(int));
	printf("%d\n", ret);
	return 0;
}

运行结果:
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

【C++杂货铺】set 和 map 使用总结

文章目录 一、前言1.1 关联式容器1.2 键值对1.3 树型结构的关联式容器 二、set2.1 set的介绍2.2 set的使用2.2.1 set 的模板参数列表2.2.2 set 的构造2.2.3 set 的迭代器2.2.4 set 的容量2.2.5 set 修改操作2.2.6 set 的使用举例 三、multiset3.1 multiset 的介绍3.2 multiset …

C++goto语句

在本文中&#xff0c;您将了解goto语句&#xff0c;它是如何工作的&#xff0c;以及为什么应该避免它。在C 编程中&#xff0c;goto语句用于通过将控制权转移到程序的其他部分来更改程序执行的正常顺序。 goto语句的语法 goto label; ... .. ... ... .. ... ... .. ... label…

【C++】笔试训练(三)

目录 一、选择题二、编程题1、字符串中找出连续最长的数字串2、数组中出现次数超过一半的数字 一、选择题 1、以下程序的输出结果是&#xff08;&#xff09; #include <stdio.h> int main() {char a[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }, * p;int i;i 8;p a i;p…

【考研数学】高等数学第七模块 —— 曲线积分与曲面积分 | 3. 对面积的曲面积分(第一类曲面积分)

文章目录 二、曲面积分2.1 对面积的曲面积分&#xff08;第一类曲面积分&#xff09;2.1.1 问题引入 —— 曲面的质量2.1.2 对面积的曲面积分定义及性质2.1.3 对面积的曲面积分的计算法 写在最后 二、曲面积分 2.1 对面积的曲面积分&#xff08;第一类曲面积分&#xff09; 2…

小谈设计模式(12)—迪米特法则

小谈设计模式&#xff08;12&#xff09;—迪米特法则 专栏介绍专栏地址专栏介绍 迪米特法则核心思想这里的“朋友”指当前对象本身以参数形式传入当前对象的对象当前对象的成员变量直接引用的对象目标 Java程序实现程序分析 总结 专栏介绍 专栏地址 link 专栏介绍 主要对目…

【自定义类型】--- 位段、枚举、联合

&#x1f493;博客主页&#xff1a;江池俊的博客⏩收录专栏&#xff1a;C语言进阶之路&#x1f449;专栏推荐&#xff1a;✅C语言初阶之路 ✅数据结构探索&#x1f4bb;代码仓库&#xff1a;江池俊的代码仓库&#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐ 文…

Hypermesh联合LS-DYNA的子弹侵彻计算

Hypermesh凭借强大的网格划分和方便的求解设置功能而被广泛用于DYNA求解器的前处理。本文通过bullet穿透铝合金板侵彻计算来简单介绍Hypermesh和LS-DYNA的联合使用。 计算模型如图1所示&#xff0c;为1/4模型&#xff0c;bullet材料为钢材&#xff0c;被穿透的板为铝合金AL202…

python和java类的编写(属性私有化,方法公开化)

初始化类的属性的2种写法&#xff1a; 如下要注意python对文件名称、类、方法名的命名 方式一&#xff1a;原始的定义 class User1: # 初始化账号和密码 def __init__(self):# 账号和密码self.__username Noneself.__password Nonedef getnsername(self):return self.__us…

001 Python开发环境搭建

1、下载python 2023/10 python-3.11.5-amd64.exehttps://www.python.org/ftp/python/3.11.5/python-3.11.5-amd64.exe 2、下载Visual Studio Code 2023/10 VSCodeSetup-x64-1.82.2.exehttps://code.visualstudio.com/docs/?dvwin64 3、安装python 双击打开python-3.11.5-a…

【Linux】RPM包使用详解

&#x1f341; 博主 "开着拖拉机回家"带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——&#x1f390;开着拖拉机回家_大数据运维-CSDN博客 &#x1f390;✨&#x1f341; &#x1fa81;&#x1f341; 希望本文能够给您带来一定的帮助&#x1f338;文…

为什么都说NFS读写性能差,如何进行优化?

使用基于NFS协议存储系统的同学经常遇到的问题是在小文件比较多的情况下性能会比较差。小文件访问性能差本身是可以理解的,但是NFS确实是太差了。不知大家是否深层次分析过,为什么NFS访问小文件性能会这么差? NFS文件系统与本地文件系统的差异在于多了一个网络传输的过程。…

阿里云RDS关系型数据库详细介绍_多版本数据库说明

阿里云RDS关系型数据库大全&#xff0c;关系型数据库包括MySQL版、PolarDB、PostgreSQL、SQL Server和MariaDB等&#xff0c;NoSQL数据库如Redis、Tair、Lindorm和MongoDB&#xff0c;阿里云百科分享阿里云RDS关系型数据库大全&#xff1a; 目录 阿里云RDS关系型数据库大全 …

AI标注,怎么做才能省时省劲,提高效率?有何技巧?

AI标注是一种借助人工智能技术为数据集添加标签的方法&#xff0c;这一过程旨在使机器学习算法能够更好地识别和分类数据。与传统手工标注相比&#xff0c;AI标注具有高效、高准确性和低成本等优势。在本文中&#xff0c;我们将探讨如何实施有效的AI标注策略以提高工作效率。 …

如何使用ChatGPT来辅助写简历

How to ask ChatGPT for resume help https://www.producthunt.com/stories/how-to-ask-chatgpt-for-resume-help #MixCopilot 本文作者&#xff1a; 摘要&#xff1a; 本文介绍了如何使用ChatGPT来辅助写简历。通过ChatGPT&#xff0c;你可以改善简历的格式和结构&#xff0c;…

基于Java的实验室设备借用登记系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

Java生态系统的进化:从JDK 1.0到今天

文章目录 JDK 1.0&#xff1a;开启Java时代JDK 1.1&#xff1a;Swing和内部类JDK 1.2&#xff1a;Collections框架和JIT编译器JDK 1.5&#xff1a;引入泛型和枚举JDK 1.8&#xff1a;Lambda表达式和流JDK 11以后&#xff1a;模块化和新特性未来展望1. 云原生和容器化2. 更好的性…

SpringBoot 如何解决跨域问题

Spring Boot 中的跨域请求&#xff08;Cross-Origin Request&#xff09;问题与解决方案 跨域请求是指浏览器从一个域名的网页去请求另一个域名的资源&#xff0c;它是为了增强 Web 安全性而产生的限制。Spring Boot 应用程序通常会面临跨域请求的问题&#xff0c;本文将介绍跨…

Java栈的压入、弹出序列(详解)

目录 1.题目描述 2.题解 方法1 方法2 1.题目描述 输入两个整数序列&#xff0c;第一个序列表示栈的压入顺序&#xff0c;请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序&#xff0c;序列4,5,3,2,1是该压栈序…

初识动态内存分配

目录 为什么会存在动态内存分配&#xff1a; malloc: free&#xff1a; calloc&#xff1a; realloc&#xff1a; 注意事项&#xff1a; 攻破经典易错题&#xff1a; 题目一&#xff1a; 存在以下两种方式进行修改&#xff1a; 1.利用二级指针进行修改&#xff1a; 2.…