【C/C++】IO流
目录
前言:
一,C语言的I/O流
二,C++的I/O流
2-1,C++标准IO流
2-2,IO流的连续输入
前言:
“流”即是流动的意思,是物质从一处向另一处流动的过程,是对一种有序连续且具有方向性的数据的抽象描述。I/O是指输入输出设备。C/C++的I/O流是指信息从外部输入设备(如键盘)向计算机内部(如内存)输入和从内存向外部输出设备(显示器)输出的过程。它的特性是有序连续性和方向性。
一,C语言的I/O流
C语言中我们用到的最频繁的输入输出方式就是scanf()与printf()。scanf 从标准输入设备(键 盘)读取数据,并将值存放在变量中。printf 将指定的文字/字符串输出到标准输出设备(屏幕),注意宽度输出和精度输出控制。除此外C语言还提供了类似于fprintf、fscanf等等专门控制I/O的函数接口。C语言借助了相应的缓冲区来进行输入与输出(缓冲器的专门讲解:缓冲区),如下图所示:
输入输出缓冲区优点:
1,可以屏蔽掉低级I/O的实现,低级I/O的实现依赖操作系统本身内核的实现,所以如果能够屏蔽这部分的差异,可以很容易写出可移植的程序。
2,减少因频繁地、小块地读写数据而产生的性能开销。这里的缓冲区可一次性存入这些数据,等到刷新缓冲区时将进行输入/输出。
C语言对于I/O这块需注意缓冲区的刷新,我们来观看以下C语言的代码问题。
#include <stdio.h>
int main()
{
char password[20] = { 0 };
printf("请输入密码: ");
scanf("%s", password);
printf("请确认密码(Y/N): ");
char input = 0;
scanf("%c", &input); //注意:这块开始出问题
if (input == 'Y')
printf("确认成功\n");
else
printf("确认失败\n");
return 0;
}
scanf 函数的原理就是行缓冲,即输入回车('\n')就会刷新缓冲区。不过需要注意,用户最后输入的回车也会储存在缓冲区。上面代码的问题就出现在scanf的行刷新,当输入完 password 并回车后,缓冲区中还存在回车这个残留字符,当再次进行input流操作时,缓冲区将其字符赋给input并自动刷新(因为缓冲区已经没有数据了),即input == '\n',就会出现上面那种情况。这里需要将缓冲区里面残留字符给去掉或使用 fflush强制刷新缓冲区,但 fflush在有些编译器是没有的,它不属于C标准,不推荐使用。
#include <stdio.h>
int main()
{
char x = 0, y = 0;
scanf("%c", &x);
printf("x = %c\n", x);//将缓冲区中的'\n'拿出,即清理缓冲区,若需要清理大部分字符,这里要使用循环语句
getchar();
scanf("%c", &y);
if (y == '\n')
printf("y == \\n\n");
else
printf("y = %c\n", y);
return 0;
}
输出一:没有getchar清理缓冲区字符
输出二:getchar清理缓冲区字符
二,C++的I/O流
2-1,C++标准IO流
C++的I/O底层原理与C语言一样,但C++系统实现了一个庞大的类库来实现I/O流操作,其中ios为基类,其他类都是直接或间接派生自ios类。
其中,istream
(输入流)和ostream
(输出流)是I/O(输入/输出)流类的重要组成部分,它们定义了进行I/O操作的基本接口。cin、cout、cerr、clog都是istream
和ostream
的实例。这两个类及其派生类(如ifstream
、ofstream
等)允许程序员以一种简洁且灵活的方式与各种数据源(如文件、控制台等)进行交互。
istream
(输入流)定义了从数据源(如文件、控制台等)读取数据的基本操作,它包含了一系列以 operator>>
形式出现的成员函数,用于读取不同类型的数据。其中我们常用于从控制台读取数据的cin就是istream
的一个实例,而cin只有把输入缓冲区中的数据取完后(即刷新缓冲区),才要求输入新的数据,补足了C语言的scanf的缺陷。
ostream
(输出流)定义了向数据目标(如文件、控制台等)写入数据的基本操作,它包含了一系列以 operator<<
形式出现的成员函数,用于写入不同类型的数据。其中我们常用于向控制台写入数据的cout
就是ostream
的一个实例,而平常与cout
连用的std::endl
操作符不仅插入了一个换行符,还刷新了与std::cout
关联的输出缓冲区。
C++标准IO流除了cout标准输出和cin标准输入外,还有cerr用来进行标准错误的输出,以及clog进行日志的输出。从上图可以看出,cout、 cerr、clog是ostream类的三个不同的对象,因此这三个对象现在基本没有区别,只是应用场景不同,一般情况下cout用的比较多。
C++的标准IO流之所以能够直接输出内置类型数据,是因为标准库已经将所有内置类型的输入和输出全部重载了。对于自定义类型,若需要支持cin和cout的标准输入输出,需要对 << 和 >>进行重载。
总的来说,C++的IO流是使用面向对象+运算符重载的方式实现的,它识别类型的本质是函数重载,内置类型可以直接使用是因为库里面istream/ostream类型已经实现了,自定义类型则需要自己重载<< 和 >>,也就是说C++的这种IO模式能够更好的兼容自定义类型,流插入和流提取。
2-2,IO流的连续输入
编程算法中有些情况会出现不断输入的情况,如:while (cin >> a){.....},结束输入的情况很多时候都是使用快捷键:Ctrl + c解决(Ctrl + c是向系统内部发送结束当前进程的信号,直接暴力杀死进程)。
实际上我们看到使用while (cin >> a){.....}去流中提取对象数据时,调用的是operator>>,返回值是 istream类型的对象,即while(cin >> a)实际上是while (operator>>(cin, a)),那么这里可以做逻辑条件值,源自于istream的对象又调用了operator bool(),operator bool()调用时如果接收流失败或有结束标志时,则返回false。任何类型只要想判断,只用重载一个operator bool()即可。
class Date
{
friend ostream& operator << (ostream& out, const Date& d);
friend istream& operator >> (istream& in, Date& d);
public:
Date(int year = 1, int month = 1, int day = 1)
:_year(year)
, _month(month)
, _day(day)
{}
//重载bool类型,用于循环语句的判断
operator bool()
{
//这里假设输入_year为0时结束
if (_year == 0)
return false;
else
return true;
}
private:
int _year;
int _month;
int _day;
};
//实现Date类的流插入和流提取
istream& operator >> (istream& in, Date& d)
{
in >> d._year >> d._month >> d._day;
return in;
}
ostream& operator << (ostream& out, const Date& d)
{
out << d._year << " " << d._month << " " << d._day;
return out;
}
int main()
{
Date d(2024, 6, 7);
cout << "输出: " << d << endl;
while (d)
{
cin >> d;
cout << "输出: " << d << endl;
}
return 0;
}
相关文章:

【C/C++】IO流
目录 前言: 一,C语言的I/O流 二,C的I/O流 2-1,C标准IO流 2-2,IO流的连续输入 前言: “流”即是流动的意思,是物质从一处向另一处流动的过程,是对一种有序连续且具有方向性的数据…...

Vite5+Vue3整合Tailwindcss详细教程
创建vite项目 执行命令: npm create vite启动项目 npm install -g pnpm pnpm i pnpm dev浏览器访问 http://localhost:5174/ 整合Tailwindcss 安装依赖 pnpm install -D tailwindcss postcss autoprefixer初始化配置文件 npx tailwindcss init用webstorm打开…...

小程序 UI 风格魅力非凡
小程序 UI 风格魅力非凡...
【常用工具系列】Git 教程——从入门到大师
目录 前言一、Git 基础1-1、Git 简介与安装安装 Git 1-2、 Git 工作流程1-3、 Git 配置与管理用户配置查看配置 1-4、 Git 仓库操作克隆仓库推送更改拉取更新 1-5 Git 分支管理创建分支切换分支删除分支解决冲突 二、 Git 进阶2-0、 Git 标签使用创建标签查看标签检出标签推送标…...

每天坚持写java锻炼能力---第一天(6.4)
今天的目标是菜单: B站/马士兵的项目菜单 package java1;import java.util.Scanner;public class Test {public static void main(String[] args) {while(true){ //3.加入死循环,让输入一直有System.out.println();System.out.println("--->项…...
mysql 如何分布式部署
MySQL的分布式部署是一个涉及多个步骤和配置的过程,以确保数据库系统能够支持大规模数据存储、高并发访问和容错性。以下是MySQL分布式部署的主要步骤和要点,结合参考文章中的相关信息进行整理: 一、前期准备 环境准备: 选择合…...

Git的概念
Git 一些概念 **工作区:**电脑上你能看到的目录 **版本库:**工作区的隐藏目录.git。含 暂存区:git add后但未git commit的文件修改被添加到暂存区本地分支:git commit后,但未git push,即把暂存区的所有…...

【每日刷题】Day58
【每日刷题】Day58 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 3038. 相同分数的最大操作数目 I - 力扣(LeetCode) 2. 868. …...
Python 的七个HTTP请求库对比
Python HTTP请求库对比 库名称特点优点缺点requests简单易用的HTTP库,基于urllib3。- 语法简洁- 社区支持强大- 易于上手和维护- 阻塞式调用,不支持异步操作- 相比aiohttp体积较大http.clientPython标准库中的低级HTTP库。- 无需安装第三方库- 提供底层…...

顶顶通呼叫中心中间件-如何配置识别不同语种的ASR
文章目录 前言联系我们创建不同语种的语音识别任务开始对接识别不同语种的ASR重启 asrproxy 程序使用识别不同语种的ASR 前言 之前讲过顶顶通的 asrproxy 程序如何对接第三方的ASR,比如:阿里云的ASR。不知道如何对接的,可以参考:…...
C# SolidWorks 二次开发-显示配置
在 SolidWorks 的二次开发中,显示配置(Display States)是一个非常重要的功能。显示配置允许用户在同一个配置(Configuration)下保存不同的显示状态,如隐藏或显示的零件、不同的颜色和材质等。本文将向新的开…...
PXE自动装机
一、PXE概述 PXE:c/s架构,允许客户端通过网络从远程服务器(服务端)下载引导镜像,加载安装文件,实现自动化安装操作系统。 c/s 架构:服务端和客户端都可以是多台。 无人值守:安装选…...

MQ之初识kafka
1. MQ简介 1.1 MQ的诞生背景 以前网络上的计算机(或者说不同的进程)传递数据,通信都是点对点的,而且要实现相同的协议(HTTP、 TCP、WebService)。1983 年的时候,有个在 MIT 工作的印度小伙突发…...

linux驱动学习(七)之混杂设备
需要板子一起学习的可以这里购买(含资料):点击跳转 一、混杂设备 混杂设备也叫杂项设备,是对普通的字符设备(struct cdev)的一种封装,设计目的就是为了简化字符设备驱动设计的流程。具有以下特点: 1) 主设备号为10&a…...
【数据结构与算法 | 堆篇】力扣215, 703
1. 力扣215 : 数组中的第k个最大元素 (1). 题 给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。 请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。 你必须设计并实现时间复杂度为 O(n) 的算法解…...

项目经理进入职场都会经历的三个阶段
对于项目经理而言,进入职场是一个不断学习和成长的过程。在这个过程中,项目经理通常会经历三个主要阶段,每个阶段都有其独特的特点和挑战。 一、基础建设与学习阶段 对于新入行的项目经理来说,最初的阶段主要是基础技能的积累和…...
消防设施工程乙级资质全解析:申请条件与流程“
消防设施工程乙级资质全解析:申请条件与流程 消防设施工程乙级资质,作为衡量企业从事特定规模消防设施设计能力的重要标尺,对于想要在消防工程领域拓展业务的企业而言至关重要。本文将全面解析申请消防设施工程乙级资质所需的条件、流程及相…...

【C语言】03.分支结构
本文用以介绍分支结构,主要的实现方式为if语句和switch语句。 一、if语句 1.1 if语句 if (表达式)语句表达式为真则执行语句,为假就不执行。在C语言中,0表示假,非0表示真.下图表示if的执行过程: 1.2 else语句 当…...
uniapp手机屏幕左滑返回上一页支持APP,H5
核心:touchstart"touchStart" touchend"touchEnd" 代码示例: <template><view class"payPasswordSetting" touchstart"touchStart" touchend"touchEnd"></view> </template&g…...

【Java毕业设计】基于JavaWeb的洗衣店管理系统
文章目录 摘要ABSTRACT目 录1 概述1.1 研究背景及意义1.2 国内外研究现状1.3 拟研究内容1.4 系统开发技术1.4.1 SpringBoot框架1.4.2 MySQL数据库1.4.3 MVC模式 2 系统需求分析2.1 可行性分析2.2 功能需求分析 3 系统设计3.1 功能模块设计3.2 系统流程设计3.3 数据库设计3.3.1 …...

【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...

Ubuntu系统复制(U盘-电脑硬盘)
所需环境 电脑自带硬盘:1块 (1T) U盘1:Ubuntu系统引导盘(用于“U盘2”复制到“电脑自带硬盘”) U盘2:Ubuntu系统盘(1T,用于被复制) !!!建议“电脑…...
离线语音识别方案分析
随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...