当前位置: 首页 > news >正文

【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都是istreamostream的实例。这两个类及其派生类(如ifstreamofstream等)允许程序员以一种简洁且灵活的方式与各种数据源(如文件、控制台等)进行交互。

        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流

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

Vite5+Vue3整合Tailwindcss详细教程

创建vite项目 执行命令&#xff1a; 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)

今天的目标是菜单&#xff1a; B站/马士兵的项目菜单 package java1;import java.util.Scanner;public class Test {public static void main(String[] args) {while(true){ //3.加入死循环&#xff0c;让输入一直有System.out.println();System.out.println("--->项…...

mysql 如何分布式部署

MySQL的分布式部署是一个涉及多个步骤和配置的过程&#xff0c;以确保数据库系统能够支持大规模数据存储、高并发访问和容错性。以下是MySQL分布式部署的主要步骤和要点&#xff0c;结合参考文章中的相关信息进行整理&#xff1a; 一、前期准备 环境准备&#xff1a; 选择合…...

Git的概念

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

【每日刷题】Day58

【每日刷题】Day58 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c;​​​​​​​ 1. 3038. 相同分数的最大操作数目 I - 力扣&#xff08;LeetCode&#xff09; 2. 868. …...

Python 的七个HTTP请求库对比

Python HTTP请求库对比 库名称特点优点缺点requests简单易用的HTTP库&#xff0c;基于urllib3。- 语法简洁- 社区支持强大- 易于上手和维护- 阻塞式调用&#xff0c;不支持异步操作- 相比aiohttp体积较大http.clientPython标准库中的低级HTTP库。- 无需安装第三方库- 提供底层…...

顶顶通呼叫中心中间件-如何配置识别不同语种的ASR

文章目录 前言联系我们创建不同语种的语音识别任务开始对接识别不同语种的ASR重启 asrproxy 程序使用识别不同语种的ASR 前言 之前讲过顶顶通的 asrproxy 程序如何对接第三方的ASR&#xff0c;比如&#xff1a;阿里云的ASR。不知道如何对接的&#xff0c;可以参考&#xff1a;…...

C# SolidWorks 二次开发-显示配置

在 SolidWorks 的二次开发中&#xff0c;显示配置&#xff08;Display States&#xff09;是一个非常重要的功能。显示配置允许用户在同一个配置&#xff08;Configuration&#xff09;下保存不同的显示状态&#xff0c;如隐藏或显示的零件、不同的颜色和材质等。本文将向新的开…...

PXE自动装机

一、PXE概述 PXE&#xff1a;c/s架构&#xff0c;允许客户端通过网络从远程服务器&#xff08;服务端&#xff09;下载引导镜像&#xff0c;加载安装文件&#xff0c;实现自动化安装操作系统。 c/s 架构&#xff1a;服务端和客户端都可以是多台。 无人值守&#xff1a;安装选…...

MQ之初识kafka

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

linux驱动学习(七)之混杂设备

需要板子一起学习的可以这里购买&#xff08;含资料&#xff09;&#xff1a;点击跳转 一、混杂设备 混杂设备也叫杂项设备&#xff0c;是对普通的字符设备(struct cdev)的一种封装,设计目的就是为了简化字符设备驱动设计的流程。具有以下特点&#xff1a; 1) 主设备号为10&a…...

【数据结构与算法 | 堆篇】力扣215, 703

1. 力扣215 : 数组中的第k个最大元素 (1). 题 给定整数数组 nums 和整数 k&#xff0c;请返回数组中第 k 个最大的元素。 请注意&#xff0c;你需要找的是数组排序后的第 k 个最大的元素&#xff0c;而不是第 k 个不同的元素。 你必须设计并实现时间复杂度为 O(n) 的算法解…...

项目经理进入职场都会经历的三个阶段

对于项目经理而言&#xff0c;进入职场是一个不断学习和成长的过程。在这个过程中&#xff0c;项目经理通常会经历三个主要阶段&#xff0c;每个阶段都有其独特的特点和挑战。 一、基础建设与学习阶段 对于新入行的项目经理来说&#xff0c;最初的阶段主要是基础技能的积累和…...

消防设施工程乙级资质全解析:申请条件与流程“

消防设施工程乙级资质全解析&#xff1a;申请条件与流程 消防设施工程乙级资质&#xff0c;作为衡量企业从事特定规模消防设施设计能力的重要标尺&#xff0c;对于想要在消防工程领域拓展业务的企业而言至关重要。本文将全面解析申请消防设施工程乙级资质所需的条件、流程及相…...

【C语言】03.分支结构

本文用以介绍分支结构&#xff0c;主要的实现方式为if语句和switch语句。 一、if语句 1.1 if语句 if (表达式)语句表达式为真则执行语句&#xff0c;为假就不执行。在C语言中&#xff0c;0表示假&#xff0c;非0表示真.下图表示if的执行过程&#xff1a; 1.2 else语句 当…...

uniapp手机屏幕左滑返回上一页支持APP,H5

核心&#xff1a;touchstart"touchStart" touchend"touchEnd" 代码示例&#xff1a; <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 …...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...