C语言——字符函数和字符串函数(下)

引言

在上一篇中,我们介绍了字符函数和一些字符串函数,在这一篇章中,我们会继续学习字符串函数,那我们现在就开始学习吧!!!

字符串函数

strncpy

1.strncpy的用法

strncpy是一个在C语言中常用的字符串处理函数,用于将源字符串的前n个字符复制到目标字符串中。其函数原型为:

char *strncpy(char *dest, const char *src, size_t n);

其中,参数的含义如下:

dest 是目标字符串,即你想要将源字符串的字符复制到的位置

src 是源字符串,即你想要从中复制字符的字符串

n 是你想要从源字符串中复制的字符数

如果源字符串的长度小于 n,strncpy 会复制源字符串的所有字符到目标字符串中,并在目标字符串的剩余位置上用 \0 填充,直到总共复制了 n 个字符

2.strncpy的使用

当src的字符串长度>=n

int main()
{char src[12] = "hello world";char dest[] = "xxxxxxxxxxxx";strncpy(dest, src, 5);printf("最终的目标字符串:%s\n", dest);return 0;
}

运行结果为:

最终的目标字符串:helloxxxxxxx

当src的字符串长度<n

int main()
{char src[25] = "hello world";char dest[] = "xxxxxxxxxxxxxx";strncpy(dest, src, 20);printf("最终的目标字符串:%s\n", dest);return 0;
}

运行结果为:

最终的目标字符串:hello world

3.strncpy的模拟实现

思路:通过自定义的 my_strncpy 函数,将源字符串 str2 的 n 个内容复制到目标字符串 str1 中,确保复制操作安全进行(通过断言检查指针非空),并返回目标字符串的起始地址。

代码如下:

char* my_strncpy(char* dest,const char* src,size_t n)
{// 断言dest和src不是空指针,以确保它们是有效的内存地址assert(dest && src);// 保存dest的原始地址,以便稍后返回char* ret = dest;// 循环复制字符,直到遇到源字符串的结束符'\0',或者复制了n个字符while (*src && n){*dest = *src;dest++;src++;n--;	// 递减n,表示已经复制了一个字符}// 如果n不为0,说明还有剩余的空间需要填充null终止符if (n != 0){while (n){*dest = '\0';dest++;n--;}}return ret;
}int main()
{char arr1[10] = "abcdef";char arr2[] = "bbq";my_strncpy(arr1, arr2, 3);printf("%s\n", arr1);return 0;
}

strncat

1.strncat的用法

strncat()函数是C语言中的一个字符串函数,用于将一个字符串的前n个字符连接到另一个字符串的末尾。

函数的原型为:

char *strncat(char *dest, const char *src, size_t n);

其中,参数的含义如下:

dest:目标字符串,即要将源字符串连接到的位置

src:源字符串,即要连接到目标字符串末尾的字符串

n:要连接的字符个数

strncat函数的工作原理是将源字符串src中的字符逐个复制到目标字符串dest的末尾,直到复制了指定的字符个数n或者遇到了源字符串的结束符'\0'。连接完成后,目标字符串dest的末尾会添加一个新的结束符'\0'。如果源字符串的长度小于n,则strncat函数会将整个源字符串连接到目标字符串的末尾。

2.strncat的使用

当src的字符串长度>n

int main()
{char str1[20] = "hello";char str2[20] = "hello world";strncat(str1, str2, 5);printf("%s\n", str1);return 0;
}

输出结果为:hellohello

当src的字符串长度<=n

int main()
{char str1[20] = "hello";char str2[20] = "hello world";strncat(str1, str2, 15);printf("%s\n", str1);return 0;
}

输出结果为:hellohello world

3.strncat的模拟实现

思路:先找到目标字符串的末尾位置,然后将源字符串的前n个字符逐个追加到目标字符串的末尾,并更新目标字符串的长度

代码如下:

char* my_strncat(char* dest, const char* src, int n)
{char* ret = dest;		//将dest首地址储存在ret中assert(dest && src);	//保证dest、src非空while (*dest != '\0')	//找到dest结尾的‘\0’{dest++;}while (n && (*dest++ = *src++))//把src里的字符一个个放入dest后{n--;                //跳出循环的条件}if (n == 0){*dest = '\0';		//如果n<src}return ret;				//返回dest字符串起始地址
}int main()
{char str1[20] = "hello ";char str2[] = "world";my_strncat(str1, str2, 5);printf("%s\n", str1);return 0;
}

strncmp

1.strncmp的用法

strncmp 是一个字符串比较函数,用于比较两个字符串的前n个字符

函数原型为:

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

其中,参数的含义如下:

str1:要比较的第一个字符串

str2:要比较的第二个字符串

n:要比较的最大字符数

返回值:

如果返回值 < 0,则表示 str1 小于 str2。

如果返回值 > 0,则表示 str1 大于 str2。

如果返回值 = 0,则表示 str1 等于 str2。

2.strncmp的使用

int main()
{char arr1[20] = "abcdef";char arr2[20] = "abcddd";char arr3[20] = "abcdff";int ret1 = strncmp(arr1, arr2, 3);int ret2 = strncmp(arr1, arr2, 8);int ret3 = strncmp(arr1, arr2, 6);int ret4 = strncmp(arr1, arr3, 6);printf("%d %d %d %d\n", ret1, ret2, ret3, ret4);return 0;
}

输出结果为:0 1 1 -1

3.strncmp的模拟实现

思路:逐个比较两个字符串的前n个字符的ASCII值,直到遇到不同字符、遇到空字符或比较完n个字符为止,根据比较结果返回相应的整数。

代码如下:

int my_strncmp(const char* str1, const char* str2, size_t n)
{assert(str1 && str2);// 如果n为0,说明不需要比较任何字符,直接返回0,表示两个字符串的前0个字符是相同的。  if (n == 0){return 0;}// 循环条件中,*str1 == *str2 确保两个字符相同,  // *str1 确保str1没有到达字符串结束符,  // --n 确保已经比较了n个字符或n已经减到0。  while (*str1 == *str2 && *str1 && --n){// 如果两个字符相同且没有到达字符串结束符,继续比较下一个字符。  str1++;str2++;}//返回的是两个字符的ASCII码差值。  return *str1 - *str2;
}int main()
{ char str1[] = "abcddd";char str2[] = "abcdef";  int ret1 = my_strncmp(str1, str2, 4);int ret2 = my_strncmp(str1, str2, 6);printf("%d %d\n", ret1, ret2);return 0;
}

strstr

1.strstr的用法

strstr用于查找一个字符串 str2 是否存在于另一个字符串 str1 中,并返回 str2 在 str1 中首次出现的位置。以下是关于strstr函数的详细介绍。

函数原型为:

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

其中,参数的含义如下:

str1:这是主串,即你希望在其中查找子串的字符串。

str2:这是子串,即你希望在主串中查找的字符串。

返回值:

如果str2是str1的子串,strstr返回一个指向str1中str2首次出现的位置的指针。

如果str2不是str1的子串,strstr返回NULL。

2.strstr的使用

int main() 
{const char* str1 = "hello world";const char* str2 = "world";char* result = strstr(str1, str2);if (result != NULL) {printf("找到了,子字符串为:%s\n", result);}else {printf("找不到\n");}return 0;
}

输出结果为:找到了,子字符串为:world

3.strstr的模拟实现

思路:通过遍历主串,依次比较每个位置开始的子串是否与目标子串匹配,直到找到匹配或遍历完整个主串

代码如下:

char* my_strstr(const char* str1, const char* str2)
{const char* s1 = NULL;	//用于遍历str1const char* s2 = NULL;	//用于遍历str2const char* cp = str1;	//指向str1的起始地址//检查传入的第二个字符串str2是否为空字符串(即只包含一个结束字符\0)//如果str2是空字符串,函数会立即返回str1的起始地址。if (*str2 == '\0')return (char*)str1;//遍历str1的字符while (*cp){s1 = cp;		//初始化s1为当前cp的位置s2 = str2;		//初始化s2为当前str2的位置//s1和s2均为到达末尾,且字符相等,则继续比较while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2){s1++;		//s1向后移动一位s2++;		//s2向后移动一位}//如果s2到达str2末尾,说明str2在str1中从cp位置被找到if (*s2 == '\0'){return (char*)cp;	//返回找到的位置的指针}cp++;			//没找到则继续遍历str1}return NULL;		//遍历完没找到则返回NULL
}int main()
{char arr1[] = "abcdef";char arr2[] = "eg";char* ret = my_strstr(arr1, arr2);if (ret == NULL)printf("找不到\n");elseprintf("%s\n", ret);return 0;
}

strtok

1.strtok的用法

strtok用于分割字符串,该函数的主要目的是将字符串按照指定的分隔符切分成多个子串,并返回指向这些子串的指针。

函数原型为:

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

其中,参数的含义如下:

str:在第一次调用时,str是传入需要被切割字符串的首地址;在后续调用时,str应设置为NULL,以便strtok函数能够在之前的位置基础上继续查找下一个标记。

sep:这是一个字符串,它定义了用作分隔符的字符集合。字符串中的每个字符都会被当作一个分割符。

工作机制:

1.strtok在str字符串中查找由sep字符串定义的分隔符。当找到分隔符时,strtok会将其替换为\0字符,从而结束当前子串。

2.strtok返回指向当前找到的子串的指针。这个子串是从str开始,到当前找到的分隔符(现在已替换为\0)结束的部分。

3.在第一次调用之后,strtok会保存其在str中的位置,以便在后续调用时能够继续查找下一个子串。因此,在后续的调用中,需要将str参数设置为NULL。

4.如果字符串中不存在更多的分隔符,strtok将返回NULL指针。

需要注意的是,strtok函数会破坏被分解字符串的完整性。调用strtok后,原字符串str的内容会被修改,因为它会将分隔符替换为\0。因此,通常建议对原始字符串进行拷贝,并在拷贝的字符串上使用strtok,以避免修改原始数据。

2.strtok的使用

int main()
{char arr1[] = "114514.2314.666";char* sep = ".";char* str = NULL;for (str = strtok(arr1, sep); str != NULL; str = strtok(NULL, sep)){printf("%s\n", str);}return 0;
}

输出结果为:

114514
2314
666

我们来分析一下:

114514.2314.666

使用strtok函数后,它会在在找到分隔符的位置后,将那个位置的字符设置为\0来结束当前的标记

然后从上一次标记的地方开始找下一个标记,直至结束

简单来说,就是”strtok会把目标字符串中间的符号作为分隔符,将目标字符串分为几个子串“

strerror

1.strerror的用法

在不同的系统和C语⾔标准库的实现中都规定了⼀些错误码,⼀般是放在 errno.h 这个头⽂件中说明的,C语⾔程序启动的时候就会使⽤⼀个全⾯的变量errno来记录程序的当前错误码,只不过程序启动的时候errno是0,表⽰没有错误,当我们在使⽤标准库中的函数的时候发⽣了某种错误,就会讲对应的错误码,存放在errno中,⽽⼀个错误码的数字是整数很难理解是什么意思,所以每⼀个错误码都是有对应的错误信息的。strerror函数就可以将错误对应的错误信息字符串的地址返回。

函数原型为:

char* strerror(int errnum);

2.strerror的使用

int main()
{int i = 0;for (i = 0; i < 10; i++){printf("%s\n", strerror(i));}return 0;
}

输出结果为:

No error(没有错误。这通常表示操作成功,没有发生任何错误)

Operation not permitted(操作不允许。这表明尝试进行的操作由于权限不足或其他限制而未能执行)

No such file or directory(没有这样的文件或目录。这通常意味着程序试图访问一个不存在的文件或目录)

No such process(没有这样的进程。这通常发生在尝试运行或管理一个不存在的进程时)

Interrupted function call(被中断的函数调用。这可能是由于某些外部因素(如用户中断)导致正在执行的函数被突然终止)

Input/output error(输入/输出错误。这通常发生在读取或写入文件或其他设备时,可能是由于设备故障、文件系统损坏或其他问题导致的)

No such device or address(没有这样的设备或地址。这通常表示程序试图访问一个不存在的设备或网络地址)

Arg list too long(参数列表过长。这通常发生在命令行参数超过系统限制时)

Exec format error(执行格式错误。这通常意味着尝试执行的程序或文件格式不正确或不被支持)

Bad file descriptor(错误的文件描述符。这通常表明程序尝试使用了一个无效或未正确初始化的文件描述符)

结束语

字符函数和字符串函数的内容就先讲到这里,下一篇文章我们将会学习内存操作函数

看到这里的友友们,感谢你们的支持,

求个点赞收藏加关注!!!

十分感谢!!!

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

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

相关文章

炫我科技:云渲染领域的佼佼者

随着数字化时代的来临&#xff0c;云渲染技术正逐渐成为影视、游戏、动画等创意产业的重要支柱。在这一领域中&#xff0c;炫我科技凭借其卓越的技术实力、优质的服务以及不断创新的精神&#xff0c;已然成为了云渲染行业的佼佼者。 炫我科技自成立之初&#xff0c;便以打造高…

全排列问题(回溯算法和深搜)

题目&#xff1a;P1706 全排列问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) #include<bits/stdc.h> using namespace std;int n,pd[110];//用来标记数字是否被使用过 int a[10]; void print(){for(int i1;i<n;i) cout<<setw(5)<<a[i];cout<<…

tkinter实现通用对账文件解析软件

软件需求 和银行等金融机构合作过程中&#xff0c;经常会有还款计划、放款文件等定时推送的文件&#xff0c;以常见的分隔符进行分隔开&#xff0c;为了在系统出现问题时&#xff0c;快速查找异常数据&#xff0c;写了一个小工具解析这些文件并写入到excel中。 软件功能 将常…

Elasticsearch-桶聚合查询详解

前言 在之前我们详细面熟了es的查询用法&#xff0c;但是es还拥有强大的聚合查询功能&#xff0c;可以得到类似分组&#xff0c;直方图&#xff0c;折线图等数据组合。类似SQL的SUM、AVG、COUNT、GROUP BY Elasticsearch-02-es的restapi使用 概念 1&#xff1a;ES聚合查询流…

是什麼讓WhatsApp行銷如此有效?

還記得在幾年前&#xff0c;WhatsAPP還是個用作於溝通的聊天工具。 但如今&#xff0c;它已轉變為強大的行銷管道&#xff0c;在全球擁有超過20億活躍使用者&#xff0c;為企業以直接、個人化和高度參與的方式與受眾建立聯繫提供了巨大的潛力。 WhatsApp 行銷和電子郵件行銷的…

Maven入门指南:构建与管理Java项目的利器

引言 在Java开发领域&#xff0c;项目构建和管理是一个至关重要的环节。随着项目规模和复杂度的不断增加&#xff0c;有效地管理项目的依赖、构建过程以及部署流程变得尤为关键。在这样的背景下&#xff0c;Apache Maven作为一款优秀的项目管理工具应运而生&#xff0c;成为了…

ChatGPT智能辅助:让学术论文写作更从容自如

ChatGPT无限次数:点击直达 html ChatGPT智能辅助&#xff1a;让学术论文写作更从容自如 引言 学术论文写作一直是许多研究者和学生头疼的问题。无论是构思文章框架、寻找合适的文献资料&#xff0c;还是整合思路、撰写论文正文&#xff0c;都是考验耐心与专业知识的过程。…

浅谈HTTP

浅谈HTTP 要通过netty实现HTTP服务器(或者客户端)&#xff0c;首先你要了解HTTP协议。 HTTP在客户端 - 服务器计算模型中用作请求 - 响应协议。 例如&#xff0c;web浏览器可以是客户端&#xff0c;并且在托管网站的计算机上运行的应用程序可以是服务器。 客户端向服务器提交…

Vue ElementPlus Input 输入框

Input 输入框 通过鼠标或键盘输入字符 input 为受控组件&#xff0c;它总会显示 Vue 绑定值。 通常情况下&#xff0c;应当处理 input 事件&#xff0c;并更新组件的绑定值&#xff08;或使用v-model&#xff09;。否则&#xff0c;输入框内显示的值将不会改变&#xff0c;不支…

异构加速GPU服务器设计方案:904-全国产化异构加速GPU服务器

全国产化异构加速GPU服务器 一、产品介绍 X7340H0是中科可控基于HYGON系列处理器开发的一款全新高端2U双路GPU服务器。X7340H0采用优异的可扩展架构设计&#xff0c;支持高密度扩展GPU加速卡&#xff0c;为深度学习推理场景提供更加安全可靠、高性价比的解决方案。 性能卓越 ●…

全志A40i android7.1 移植wifi驱动的一般流程

一&#xff0c;问题分析 一般情况下移植一款模组&#xff0c;会涉及到驱动&#xff0c;firmware, hal层&#xff0c;方案端的适配。 下面以RTL8723ds为例详细列出移植的通用步骤。 二&#xff0c;移植步骤 1. 移植Wi-Fi驱动 从RTL原厂或者已经支持的其他把内核版本中获取驱动…

C++中string容器的字符串操作

目录 1.c_str() 返回C常量字符串 2.date() 返回C常量字符串 3.substr() 构造子串 4.find() 正向查找&#xff08;查找失败返回npos&#xff09; 5.rfind() 逆向查找&#xff08;查找失败返回npos&#xff09; 6.find_first_of() 正向查找匹配的字符 7.find_last_of() 逆向…

HTML面试题:get和post的区别

get和post都是HTTP中的两种请求方式 区别一&#xff0c;参数位置&#xff1a;GET请求把参数包含在URL中&#xff0c;POST将参数包含在请求体request body中。 区别二&#xff0c;回退&#xff1a;GET在浏览器回退时是无害的&#xff0c;而POST会再次提交请求。 区别三&#…

经典文献阅读之--LOG-LIO(高效局部几何信息估计的激光雷达惯性里程计)

0. 简介 局部几何信息即法线和点分布在基于激光雷达的同时定位与地图构建&#xff08;SLAM&#xff09;中是至关重要&#xff0c;因为它为数据关联提供了约束&#xff0c;进一步确定了优化方向&#xff0c;最终影响姿态的准确性。然而即使在使用KD树或体素图的辅助下&#xff…

【CANN训练营笔记】AscendCL图片分类应用(C++实现)

样例介绍 基于PyTorch框架的ResNet50模型&#xff0c;对*.jpg图片分类&#xff0c;输出各图片所属分类的编号、名称。 环境介绍 华为云AI1s CPU&#xff1a;Intel Xeon Gold 6278C CPU 2.60GHz 内存&#xff1a;8G NPU&#xff1a;Ascend 310 环境准备 下载驱动 wget ht…

git diff

1. 如何将库文件的变化生成到patch中 git diff --binary commit1 commit2 > test.patch 打patch&#xff1a; git apply test.patch 2. 如何消除trailing whitespace 问题 git diff --ignore-space-at-eol commit1 commit2 > test.patch 打patch&#xff1a; git ap…

在 Windows 中安装部署并启动连接 MongoDB 7.x(命令行方式启动、配置文件方式启动、将启动命令安装为系统服务实现开机自启)

MongoDB 的下载 下载地址&#xff1a;https://www.mongodb.com/try/download/community 这里需要对 MongoDB 的版本号说明一下&#xff1a; MongoDB 版本号的命名规则是 x.y.z&#xff0c;当其中的 y 是奇数时表示当前的版本为开发版&#xff0c;当其中的 y 是偶数时表示当前的…

非关系型数据库之Redis配置与优化

一、关系数据库与非关系型数据库 1.1关系型数据库 关系型数据库是一个结构化的数据库&#xff0c;创建在关系模型&#xff08;二维表格模型&#xff09;基础上一般面向于记录。SQL语句&#xff08;标准数据查询语言&#xff09;就是一种基于关系型数据库的语言&#xff0c;用…

Linux入侵排查

第2篇&#xff1a;Linux 入侵排查 0x00 前言 当企业发生黑客入侵、系统崩溃或其它影响业务正常运行的安全事件时&#xff0c;急需第一时间进行处理&#xff0c;使企业的网络信息系统在最短时间内恢复正常工作&#xff0c;进一步查找入侵来源&#xff0c;还原入侵事故过程&…

【C#】数字后缀及其作用 | Numeric Literal Suffixes and Their Usage in C#

C#中的数字字面量后缀及其作用 | Numeric Literal Suffixes and Their Usage in C# 在C#编程中,我们经常需要使用不同类型的数字,如整数、浮点数和高精度数字等。为了方便表示这些数字并明确其数据类型,C#提供了各种数字字面量后缀。本文将通过实例详细介绍这些后缀的作用和用…