C语言——字符函数和字符串函数(三)【strtok,strerror,perror】

news2024/11/18 11:27:10

📝前言:
上一篇文章C语言——字符函数和字符串函数(二)对字符函数和字符串函数strstrstrcmp和strncmp进行了一定的讲解
这篇文章主要讲解以下函数的用法:
1,strtok
2,strerror
3,perror

🎬个人简介:努力学习ing
📋个人专栏:C语言入门基础
🎀CSDN主页 愚润求学
🌄每日鸡汤:知不足而奋进,望远山而前行


文章目录

  • 一,strtok的使用
    • 1,strtok初步了解
    • 2,注意事项
    • 3,返回值的不同情况
      • (1)strtok的参数1不为NULL
      • (2)strtok的参数1为NULL
      • (3)字符串中不存在更多标记
  • 二,strerror的使用
  • 三,perror的使用

一,strtok的使用

1,strtok初步了解

我们先来看一下官网对它的介绍👇🏻
在这里插入图片描述
提取出它的函数原型:char * strtok ( char * str, const char * delimiters );
①我们先分别理解这里面的参数返回类型
●参数1:str是需要分割的字符串
●参数2:delimiters是用来分割的分割符的集合
●返回:返回一个指针(下面会讲解具体的返回情况)

strtok的功能是:根据delimiters里面的分隔字符,把 str分割成不同的标记(这些标记是由分隔符中的任何字符分隔的连续字符序列。)
可能有点抽象,下面我举个例子:

比如我们要分割“zhangsan@163.com”这一个字符串
请看下面的代码👇🏻

#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = "zhangsan@163.com";
	char str[3] = { '.','@'};
	printf("%s", strtok(arr, str));
	return 0;
}

这里面arr是我们分割的字符串,str是分隔字符的集合
正常流程就是:用str中的分隔字符,把arr分成:zhangsan,163,com这几个标记

但是当我们运行,输出结果👇🏻
在这里插入图片描述
(通过这个结果我们可以猜测:printf应该是从z这个首地址开始打印,但是打印完zhangsan就停止了)
是不是这样呢?(当我们了解了strtok的返回和注意事项就会理解)👇🏻

2,注意事项

strtok函数在找到str中的下一个标记的时候,会将标记用‘\0’结尾(即可能会替换掉这个标记结尾的分隔符)
请看👇🏻
在这里插入图片描述
显而易见,当这一次strtok被调用后,找到了第一个标记zhangsan,然后把张三后面的@换成了\0
总之,strtok函数会改变被操作的字符串,因此在我们使用strtok分割字符串时,可以先把字符串拷贝一份,对拷贝的那一份进行操作,这样就不会造成原来的字符串丢失。

3,返回值的不同情况

在这里返回情况可以分为三类:
1,strtok的参数1不为NULL
2,strtok的参数1为NULL
3,字符串中不存在更多标记

(1)strtok的参数1不为NULL

这时候函数会找到str中的第一个标记,然后以\0将它结尾,并且记住这个标记结束后的位置,然后返回一个指向这个标记起始位置的指针
继续看上面用到的例子:

#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = "zhangsan@163.com";
	char str[3] = { '.','@'};
	printf("%s", strtok(arr, str));
	return 0;
}

在这里插入图片描述
在这个例子里,strtok函数返回了zhangsan的起始位置z,随后printfz位置开始打印,遇到了被strtok修改成的\0于是停止了打印

(2)strtok的参数1为NULL

strtok的参数为NULL时,函数就会从同一个字符串中被保留的位置(即上一个标记结束后的位置)开始,查找下一个标记,当找到标记后,依然是:\0将这个标记结尾,并且记住这个标记结束后的位置,然后返回一个指向这个标记起始位置的指针

请看下面的代码,依旧是要实现分割“zhangsan@163.com”这一个字符串👇🏻

#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = "zhangsan@163.com";
	char str[3] = { '.','@'};
	char* ptr = NULL; //用ptr接收返回的指针
	for (ptr = strtok(arr, str); ptr != NULL; ptr = strtok(NULL, str))          
	{
		printf("%s\n", ptr); //用ptr接收的地址打印
	}
	//用for循环可以实现第一次传入strtok的arr
	// 然后传入strtok的都是NULL
	return 0;
}

输出结果:
在这里插入图片描述
arr的变化:
在这里插入图片描述
第一次strtok返回z的地址,且strtok@改成\0ptr接收到了z的地址
第二次strtok返回1的地址,且把.改成\0ptr接收了1的地址
第三次strtok返回c的地址,且把\0改成\0(通俗理解),ptr接收了c的地址
然后根据ptr这些地址分别打印出了这些标记
那第四次,com之后找不到标记了呢?👇🏻

(3)字符串中不存在更多标记

当字符串中不存在更多标记时,函数就会返回NULL指针,这也就是为什么上面的例子中for循环的进入条件是:ptr != NULL

二,strerror的使用

头文件:<errno.h>
strerror是一个传入错误码作为参数返回参数部分错误码对应的错误信息的字符串地址的函数

先简单了解什么是错误码:
C语言程序启动的时候,如果程序出现问题,会返回一个错误码,这个错误码会被记录到errno这个全局变量中
不同的错误码都对应着不同的错误信息

使用展示👇🏻

#include <stdio.h>  
#include <errno.h>  
#include <string.h>  

int main() {
    FILE* file = fopen("nonexistent_file.txt", "r");
    if (file == NULL) {
        printf("Error opening file: %s\n", strerror(errno));
        return 1; // 返回错误码  
    }
    // ...其他代码...  
    fclose(file);
    return 0; // 返回0表示成功  
}

输出结果:
在这里插入图片描述

在这个例子中,如果文件打开失败,fopen函数会返回NULL,并且errno会记录一个表示具体错误的值。
我们使用strerror函数就可以得到错误码对应的错误信息的地址,然后打印出来。

三,perror的使用

perror函数也是一个用来打印错误码的函数
通过接受一个字符串作为参数,并把它作为错误消息输出到标准错误流
同样是上面的代码,我们修改一下,用perror👇🏻

#include <stdio.h>  
#include <errno.h>  
#include <string.h>  
  
int main() {  
    FILE *file = fopen("nonexistent_file.txt", "r");  
    if (file == NULL) {  
        perror("Error opening file");  
        return 1; // 返回错误码  
    }  
    // ...其他代码...  
    fclose(file);  
    return 0; // 返回0表示成功  
}

在这里插入图片描述
输出结果是完全一样的,perror的不同就在于,它打印完参数部分的字符串后,在打印一个:和一个 (空格),接着打印错误信息。


🌈我的分享也就到此结束啦🌈
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
📢公主,王子:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!

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

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

相关文章

线程学习(3)-volatile关键字,wait/notify的使用

​ &#x1f495;"命由我作&#xff0c;福自己求"&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;线程学习(2)​​​​ 一.volatile关键字 volatile关键字是多线程编程中一个非常重要的概念&#xff0c;它主要有两个功能&#xff1a;保证内存可见性…

如何配置TLSv1.2版本的ssl

1、tomcat配置TLSv1.2版本的ssl 如下图所示&#xff0c;打开tomcat\conf\server.xml文件&#xff0c;进行如下配置&#xff1a; 注意&#xff1a;需要将申请的tomcat版本的ssl认证文件&#xff0c;如server.jks存放到tomcat\conf\ssl_file\目录下。 <Connector port"1…

MyBatis动态SQL(常用标签)

目录 标签--if 标签--trim 标签--where 标签--set 标签--foreach 和标签--sql和include 根据需求&#xff0c;动态拼接SQL&#xff0c;下面的标签示范使用xml的方式演示。 <if>标签--if 注解&#xff1a; 1.要把全部的SQL放在script标签下 2.使用if标签 可以观…

15-网络安全框架及模型-BLP机密性模型

目录 BLP机密性模型 1 背景概述 2 模型原理 3 主要特性 4 优势和局限性 5 困难和挑战 6 应用场景 7 应用案例 BLP机密性模型 1 背景概述 BLP模型&#xff0c;全称为Bell-LaPadula模型&#xff0c;是在1973年由D.Bell和J.LaPadula在《Mathematical foundations and mod…

PLC-IoT 网关开发札记(1):存档和分发 Android App

开篇记 PLC-IoT 网关是作者开发的产品&#xff0c;根据客户需求&#xff0c;立项开发手机 App&#xff0c;为用户提供一种方便、直观、友好的设备操控方式。网关运行的是嵌入式 Linux 操作系统&#xff0c;计划通过某一种通信协议&#xff08;例如 HTTP&#xff0c;MQTT或者 T…

微信小程序预览pdf,修改pdf文件名

记录微信小程序预览pdf文件&#xff0c;修改pdf名字安卓和ios都可用。 1.安卓和苹果的效果 2.需要用到的api 1.wx.downloadFile wx.downloadFile 下载文件资源到本地。客户端直接发起一个 HTTPS GET 请求&#xff0c;返回文件的本地临时路径 (本地路径)&#xff0c;单次下载…

2024年元旦节放假通知

致尊敬的客户以及全体同仁&#xff1a; 旧岁已展千重锦&#xff0c;新年再进百尺竿。在这辞旧迎新之际&#xff0c;易天光通信提前祝您元旦快乐&#xff01;生意兴隆&#xff0c;身体健康&#xff0c;万事如意&#xff01;根据国家法定假期的规定&#xff0c;并结合公司实际情…

C# 使用Pipelines处理Socket数据包

写在前面 在上一篇中对Pipelines进行简单的了解&#xff0c;同时也留下了未解的问题&#xff0c;如何将Pipelines类库运用到Socket通讯过程中来解决粘包和分包。链接地址如下&#xff1a; 初识System.IO.Pipelines https://rjcql.blog.csdn.net/article/details/135211047 这…

嵌入式单片机的存储区域与堆和栈

一、单片机存储区域 如图所示位STM32F103ZET6的参数&#xff1a; 单片机的ROM&#xff08;内部FLASH&#xff09;&#xff1a;512KB&#xff0c;用来存放程序代码的空间。 单片机的RAM&#xff1a;64KB&#xff0c;一般都被分配为堆、栈、变量等的空间。 二、堆和栈的概念 …

深入探索Spring Boot的核心功能:快速构建原生程序响应式处理数据(文末送书)

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《linux深造日志》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! ⛳️ 写在前面参与规则 ✅参与方式&#xff1a;关注博主、点赞、收藏、评论&#xff0c;任意评论&#xff08;每人最多评论…

【linux】Linux管道的原理与使用场景

Linux管道是Linux命令行界面中一种强大的工具&#xff0c;它允许用户将多个命令链接起来&#xff0c;使得一个命令的输出可以作为另一个命令的输入。这种机制使得我们可以创建复杂的命令链&#xff0c;并在处理数据时提供了极大的灵活性。在本文中&#xff0c;我们将详细介绍Li…

什么是焊点保护胶?它的作用是什么

焊点保护胶是一种用于电子元件焊点和连接处的保护的特殊胶水。它主要作用是提供以下几点的保护和增强功能&#xff1a; 防腐蚀保护 电子元件的焊点容易受到环境中的湿度、化学物质和其他腐蚀性因素的影响。焊点保护胶能够形成一层防护膜&#xff0c;减少腐蚀的风险&#xff0c…

苏州科技大学计算机817程序设计(java) 学习笔记

之前备考苏州科技大学计算机&#xff08;专业课&#xff1a;817程序设计&#xff08;java&#xff09;&#xff09;。 学习Java和算法相关内容&#xff0c;现将笔记及资料统一整理归纳移至这里。 部分内容不太完善&#xff0c;欢迎提议。 目录 考情分析 考卷题型 刷题攻略…

Typora使用PicGo+Gitee上传图片报错403 Forbidden

Typora使用PicGoGitee上传图片报错403 Forbidden Typora使用PicGoGitee上传图片&#xff0c;上传失败了&#xff0c;错误信息如下 打开PicGo的日志文件查看&#xff0c;可以看到错误详情如下 换了一个插件github-plus重新配置&#xff0c;解决了这个问题 再打开日志查看&…

vue+element+springboot实现多张图片上传

1.需求说明 2.实现思路 3.el-upload组件主要属性说明 4.前端传递MultipartFile数组与服务端接收说明 5.完整代码 1.需求说明 动态模块新增添加动态功能,支持多张图片上传.实现过程中对el-upload组件不是很熟悉,踩了很多坑,当然也参考过别的文章,发现处…

浅谈互联网架构演变

更好的阅读体验 \large{\color{red}{更好的阅读体验}} 更好的阅读体验 前言 可以将某个项目或产品的架构体系按照如下方式分层&#xff1a; 业务层面&#xff1a;项目业务体系技术层面&#xff1a; 数据架构&#xff1a;数据持久层策略应用架构&#xff1a;应用层的实现方式 …

HBase深度历险 | 京东物流技术团队

简介 HBase 的全称是 Hadoop Database&#xff0c;是一个分布式的&#xff0c;可扩展&#xff0c;面向列簇的数据库&#xff0c;是一个通过大量廉价的机器解决海量数据的高速存储和读取的分布式数据库解决方案。本文会像剥洋葱一样&#xff0c;层层剥开她的心。 特点 首先我…

Android中_Service生命周期和AMS流程的创建

Service生命周期可以结合Android生命周期分析。 Service生命周期可以从两种启动Service的模式开始讲起&#xff0c;分别是context.startService()和context.bindService()。 Service的生命周期与启动和绑定状态相关。当调用startService()方法启动服务时&#xff0c;会执行onS…

65内网安全-域环境工作组局域网探针

这篇分为三个部分&#xff0c;基本认知&#xff0c;信息收集&#xff0c;后续探针&#xff0c; 基本认知 分为&#xff0c;名词&#xff0c;域&#xff0c;认知&#xff1b; 完整架构图 名词 dwz称之为军事区&#xff0c;两个防火墙之间的区域称之为dwz&#xff0c;但安全性…

大象机器人发布万元级水星Mercury人形机器人产品系列,联结未来,一触即达!

十四五机器人产业发展规划指出机器人的研发、制造、应用是衡量一个国家科技创新和高端制造业水平的重要标志。当前&#xff0c;机器人产业蓬勃发展&#xff0c;正极大改变着人类生产和生活方式&#xff0c;为经济社会发展注入强劲动能。 人形机器人作为机器人产业中重要的一环&…