6.7 输入输出流

输入:将数据放到程序(内存)中

输出:将数据从程序(内存)放到设备中

C++的输入输出分为3种形式:

从键盘屏幕中输入输出,称为标准IO

对于磁盘进行标准输入输出,称为文件IO

对于指定的空间进行输入输出字符串,称为串IO

cin是通用输入流的对象。

标准IO没有进行特别的规定,比较特殊和常用没有定义额外的类。

其他的输入输出流有专门定义了的类。

通用输入输出包含文件标准字符串输入输出

流的四种状态

badbit:系统错误,置位时流无法使用

failbit:可恢复的错误,想读一个int但读成了char,修改后流正常使用

eofbit:到达文件末尾,置位

goodbit:表示流是一个有效状态

当处于前三种状态时无法正常使用,但是重点关注第二种

标准输入输出

标准输入输出是在iostream这个类中,cin其实是其中的一个对象

在iostream这个类中有成员函数good()。。。

clear()调整为流的状态为goodbit,但是因为输入是字符串但是读入进行存储的地方是int类型,所以没有能够清空这个输入的缓冲区,所以需要将缓冲区进行清空。所以说clear调整流的状态需要和ignore函数结合使用,ignore默认是忽略1个字符,不要忘记忽略最后的换行符,所以说需要设置足够的可以忽略的字符数ignore(4)用来忽略you\n。这样很麻烦不确定会输入什么。

可以通过补充功能实现cin.ignore(12,'\n');

这样最多释放12个字符,不管到不到最大值字符数,直到分隔符都忽略。

所以可以设置为cin.ignore(1024,'\n');所以前面参数可以尽可能设置更大。

如果觉得还不够大使用

#include <limits>头文件中的最大数值
input.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

//记住这个前面是一个类,其中是定义的静态函数,

使用这个定义的最大的数值

下面的这个情景:当输入错误的时候,要求继续进行输入

int x;
cout << "输入:" << endl;
//,表达式依据最后的表达式,cin会执行,但是不会让while直接结束
int number = 0;
while(cin << x,++number,!cin.eof()){
    if(number > 5){
        cout << "输错超过5次" << endl;
        break;
    }
    if(cin.bad()){
        cout << "不可补救" << endl;
        return 0;
    }else if(cin.fail()){
        cin.clear();
        cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
        cout << "输入正确的格式" << endl;
    }else{
        //正确
        cout << "right" << endl;
        break;
    }
}

//asdf3后面的数字被认为是字符串的一部分,是错误的
//2sadf后面的字母并不会被读出来,留在缓冲区中,这个输入是正确的

对于流的状态进行判断的时候可以直接判断

if(cin.good()){}

if(cin){}

是同样的效果,都可以继续进行任务。

//所以说可以这样来使用
if(cin >> num){
    cout << "right !" << endl;
}

连续cin或者是cout

int a,b;
cin >> a >> b;
(cin >> a )>> b;
//两个是一样的效果
//cin语句表达式的返回值就是cin或者cout对象
如果说a输入格式不对的话,b就不会再允许进行输入

连续的输入可以通过换行来实现也可以通过空格来实现

缓冲机制

(内存)用于缓解cpu(程序)和磁盘(IO操作)的速度的差距

输入内容存在流缓冲区中,特定情况下释放

缓冲机制:

三种缓冲机制:全缓冲(填满缓冲区),行缓冲(填满一行),不缓冲

cin:全缓冲和行缓冲(换行的时候就将数据放在对应的变量)

cout:满缓冲

通过下面的例子理解:会先打印1024个a,2秒以后又打印一个a。

实际上如果是打印1500,也是会先打印1024个,然后正序结束的时候剩下的才打印。

gcc默认的缓冲区大小是1024,缓冲区满了以后先打印出来然后剩下的放在缓冲区中。

如果遇到endl就会直接刷新打印出来,或者是fflush。(endl底层实际上是刷新+换行)

1024刚好放下不会打印,2秒后打印。

无缓冲:不管来啥直接就打印出来

cerr打印错误的时候,不会使用到缓冲区,直接就打印出来,因为比较紧急。

文件输入和输出流

ifstream();
explicit ifstream(const char* filename, openmode mode = ios_base::in);
explicit ifstream(const string & filename, openmode mode = ios_base::in);

ofstream();
explicit ofstream(const char* filename, openmode mode = ios_base::out);
explicit ofstream(const string & filename, openmode mode = ios_base::out);

fstream();
explicit fstream(const char* filename, openmode mode = ios_base::in|out);
explicit fstream(const string & filename, openmode mode = ios_base::in|out);

还得需要注意哪个是输入,哪个是输出。外存文件到程序是输入,就像是cin从将键盘到内存程序

【补充】Point pt = 1; pt.print(); 这是一种隐式转换,pt就是(1,0)。但是这种格式非常的奇特,所以说采用explicit禁止这种情况

String str = "hello";

其实这也是一个隐式转换,这种隐式转换就比较正常,所以说不使用explict禁止

文件输入流

#include <fstream>
void test0(){
    ifstream ifs;
    ifs.open("test1.cc");
    
    ifstream ifs2("test2.cc");
    
    string filename = "test3.cc";
    ifstream ifs3(filename);
}
//第二个参数有默认值

无参构造的时候借助于open将创建的文件输入流与文件进行绑定,文件不存在的时候流的状态变为failbit状态,这个时候添加一个判断语句。

ifstream ifs;
if(!ifs){
    cout << "file is not exist! " << endl;
    return;
}

通过上一部分可以知道可以在一开始的时候就和文件进行绑定,也可以一开始使用无参构造,然后

使用open函数与文件进行绑定。

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main()
{
    ifstream ifs;
    ifs.open("string.cc");

    if(!ifs){
        cerr << "file error" << endl;
        return ;
    }    


    //1.c风格字符串不常用
    char buf[100];
    while(ifs.getline(buf, sizeof(buf))){
        cout << buf << endl;
        memset(buf, 0, sizeof(buf));
        //c风格字符串记得清0不像c++可以自己处理空间且不用清理
    }


    //2.C++风格
    string line;
    while(getline(ifs,line)){
        cout << line << endl; 
    }
    
    cout << endl;
    return 0;
}

第二种c++风格中的getline函数是用到istream中的getline成员函数,ifstream是istream的派生类。

读取指定字节数的内容

read函数 + seekg函数 + tellg函数

seekg用来设置游标的位置,tellg用来获取游标的位置

seekg有两种方式可以进行位置的获取,一种是绝对位置的设置另外一种是相对位置的设置方式

(1)seekg(30)偏移到第30个位置 (2)seekg(0, std::ios::end)

打开的时候就立即让游标移到末尾的位置

重要读取配置文件的时候会使用到,文件的io

文件输出流

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main()
{
    ofstream ofs("1.txt", std::ios::app);

    if(!ofs){
        cerr << "file error " << endl;
        return 0;                        
    } 
    string str("hello");
       
    ofs << str;

    ofs.close();
    return 0;
}

打开ofstream的时候使用参数app的方式打开的话,就会追加的方式打开。

下面这种方式就是可以在另外的一个窗口中动态的查看文件的内容。

【注意】文件不存在时候不会报错,会创建文件,不像读入文件一样

字符串输入输出流

字符串输入流

#include <iostream>
#include <sstream>
#include <string>

using namespace std;
int main()
{
    string str = "22313                12"; 
    int num1, num2;
    istringstream iss(str);
    iss >> num1 >> num2;
    cout << num1 << "     " << num2 << endl;
    return 0;
}

这样num1和num2就被赋初值。

这样就非常方便去读配置文件

【注意】注意一个一个小细节就是使用const引用,可以避免修改和复制以及可能会绑定右值问题

#include <iostream>                   
#include <fstream>
#include <sstream>
#include <string>   

using namespace std;

int main()
{
    ifstream ifs("my.conf");
    if(!ifs){
        cerr << "file error" << endl;
        return 0;
    }
    string line;
    while(getline(ifs, line)){
        istringstream iss(line);
        string temp, use;
        iss >> temp >> use;
        cout << temp << ": " << use;
        /* iss.close(); */
    }

    ifs.close();

    return 0;
}

读取配置文件的过程:

通过ifstream打开文件,一次读取出来一行。

通过istringstream将一行赋给字符串输入流,实际上就是建立一个缓冲区,然后自己通过空格挨个读取出来

【注意】这个地方其实就是实现了类型的转换从string类型转换为int类型

【补充】

cout cin cerr都是对象

endl是inline函数

std::string  std::isatream 是一个类

字符串输出流

void test0(){
    int num = 123, num2 = 456;
    ostringstream oss;
    //把所有的内容都传给了字符串输出流对象
    oss << "num = " << num << " , num2 = " << num2 << endl;
    cout << oss.str() << endl;
}

就是将一长串任何类型的数据转换为一个string类型的数据

string可以直接用+,也可以用append,但是这两种不能跨类型实现不能string str = "hello" + 2;

可以通过std::to_string(1)变为string类型的数据。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

容声冰箱正式发布主动除菌净味白皮书,守护家人饮食健康

近日&#xff0c;由中国家用电器研究院指导、全国家用电器工业信息中心和容声冰箱联合编制的《冰箱主动除菌净味技术发展白皮书》&#xff08;下称《白皮书》&#xff09;正式发布。 《白皮书》指出&#xff0c;容声将IDP主动除菌技术应用到冰箱冷冻、冷藏区域&#xff0c;实现…

u盘内容无故消失了是什么原因?u盘部分内容无故消失了怎么恢复

在数字化时代&#xff0c;U盘作为便携存储设备&#xff0c;承载着许多重要的数据。然而&#xff0c;有时我们可能会遭遇U盘部分内容无故消失的情况&#xff0c;这无疑给我们的工作和生活带来了不小的困扰。本文将为您解析U盘内容消失的可能原因&#xff0c;并分享几招实用的数据…

数据结构--线性表和串

个人介绍 hello hello~ &#xff0c;这里是 code袁~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的…

[职场] 社保和商业保险有什么区别?可以只买商保不买社保吗? #微信#经验分享#媒体

社保和商业保险有什么区别&#xff1f;可以只买商保不买社保吗&#xff1f; 我们在提到社保和商业保险时&#xff0c;经常会听到这样一句话&#xff1a;“社保是基础&#xff0c;商保是补充。” 为什么会这样说呢&#xff1f;社保和商保有什么区别呢&#xff1f;今天&#xf…

UE5中在地形中加入湖、河

系统水资产添加 前提步骤123 完成 前提 使用版本 UE5.0.3,使用插件为UE内置的Water和water Extras. 步骤 1 记得重启 2 增加地形&#xff0c;把<启用编辑图层>勾选 如果地形没有勾选上编辑图层&#xff0c;那么就会导致湖、河等水景象无法融入地形。 如果忘记勾选…

分享飞行棋夫妻互动游戏高阶版,揭秘夫妻飞行棋游戏玩法!

朋友们&#xff0c;今天我要给你们介绍一款超级甜蜜的小游戏——情侣飞行棋。别小看它&#xff0c;这可不是咱们小时候玩的那种&#xff0c;这是专门为咱们这些恩爱的小两口设计的&#xff0c;能让你们的感情在游戏中更加甜蜜蜜&#xff0c;擦出更多爱的火花。 准备好了吗&…

帕友饮食改善的小建议!

一、增加膳食纤维的摄入 帕金森病患者应增加膳食纤维的摄入量&#xff0c;以帮助调节肠道功能&#xff0c;预防便秘。膳食纤维丰富的食物包括蔬菜、水果、全谷类食物等。患者应确保每天摄入足够的膳食纤维&#xff0c;以保持肠道通畅&#xff0c;缓解帕金森病可能带来的消化不…

如何将HTTP升级成HTTPS?既简单又免费的方法!

在当今数字化时代&#xff0c;网络安全已成为用户和企业关注的焦点。HTTPS作为一种更加安全的网络通信协议&#xff0c;正逐渐取代传统的HTTP成为新的标准。对于许多网站管理员和内容创作者来说&#xff0c;如何免费升级到HTTPS是一个值得探讨的问题。本文将详细介绍一些免费的…

6.18云服务器大促盘点,错过一次,再等一年!

随着云计算技术的飞速发展&#xff0c;云服务器已成为企业和个人构建和扩展在线业务的首选平台。特别是在大型促销活动如618年中大促期间&#xff0c;云服务提供商纷纷推出极具吸引力的优惠&#xff0c;以降低用户上云的门槛。以下是对当前市场上几个主流云服务提供商的优惠活动…

基本 MOSFET 恒流源

恒流源在电路分析练习和网络定理中占有重要地位&#xff0c;然后它们似乎或多或少消失了。。。除非你是IC设计师。尽管在典型 PCB 设计中很少遇到&#xff0c;但电流源在模拟 IC 领域却无处不在。这是因为它们 1) 用于偏置&#xff0c;2) 作为有源负载。 偏置&#xff1a; 用作…

代码随想录算法训练营第五十三天 | 309.最佳买卖股票时机含冷冻期、714.买卖股票的最佳时机含手续费

309.最佳买卖股票时机含冷冻期 视频讲解&#xff1a;动态规划来决定最佳时机&#xff0c;这次有冷冻期&#xff01;| LeetCode&#xff1a;309.买卖股票的最佳时机含冷冻期_哔哩哔哩_bilibili代码随想录 解题思路 1. dp[i][0] 第i天持有股票的状态 dp[i][1]第i天不持股的状…

毫米波SDK使用2

5.5 毫米波SDK-TI组件 毫米波SDK功能分解成组件将在接下来的几小节中解释。有关这些模块的详细文档&#xff0c;请参阅位于mmwave_mcuplus_sdk_<ver>/docs/mmwave_sdk_module_document .html的顶层文档。 5.5.1 演示 5.5.1.1 毫米波演示 这个演示位于mmwave_mcuplus_sd…

React的表单学习

react的表单的双向绑定 // userState实现计数实例 import {useState} from react// 1.声明一个react的状态 -useState// 2.核心绑定流程//1.通过value属性绑定react状态//2.绑定onChange事件&#xff0c;通过事件参数e拿到输入框最新的值&#xff0c;反向修改到react状态 func…

最佳实践的实践 - API 不应将 HTTP 重定向到 HTTPS

原文&#xff1a;jviide - 2024.05.23 TL;DR: 与其将 API 调用从 HTTP 重定向到 HTTPS&#xff0c;不如让失败显而易见。要么完全禁用 HTTP 接口&#xff0c;要么返回明确的 HTTP 错误响应&#xff0c;并撤销通过未加密连接发送的 API 密钥。遗憾的是&#xff0c;许多知名的 A…

GSS7000卫星导航模拟器结合RTKLIB 接收NTRIP网络RTCM数据以输出RS232

本文聚焦&#xff0c;使用GSS7000仿真GNSS NTRIP&#xff0c;利用开源工具RTKLIB 作为NTRIP Client 接受GSS7000仿真的RTCM数据&#xff0c; 并通过STRSVR将收到的RTCM数据通过USB-RS232数据线吐出&#xff0c;并转给DUT&#xff0c;让其获得RTK -FIXED 固定解。 废话不多说&a…

vue3中的ref与reactive的区别

目录 1、两者的区别底层实现响应式引用与响应式对象 2、用法3、vue3中声明的数组/对象3.1 通过reactive 声明的Array/Object&#xff0c;给它重新分配一个全新的对象时&#xff0c;会出错、或失去响应式效果 3.2 解决方案 4、cosnt 说明5、Proxy 与 definePropertyref 浅层响应…

数据结构--二叉树(二)

链式二叉树 链式二叉树是链式树集合中的一种&#xff0c;该树的每个根节点最多只有两个孩子节点&#xff0c;我们一般用左右孩子来称呼&#xff0c;在初学链式二叉树时&#xff0c;由于大家对链式二叉树的结构掌握还不够深入&#xff0c;为了降低本章的学习难度及成本&#xff…

pytorch构建模型训练数据集

pytorch构建模型训练数据集 pytorch构建模型训练数据集1.AlexNet:1.1.导入必要的库&#xff1a;1.2.数据预处理和增强&#xff1a;1.3.加载数据集&#xff1a;1.4.划分测试集和训练集&#xff1a;1.5.创建数据加载器&#xff1a;1.6.加载AlexNet模型&#xff1a;1.7.修改模型以…

Oracle EBS AP发票创建会计科目错误:子分类帐日记帐分录未按输入币种进行平衡

系统版本 RDBMS : 12.1.0.2.0 Oracle Applications : 12.2.6 问题症状: 提交“创建会计科目”请求提示错误信息如下: 中文报错: 该子分类帐日记帐分录未按输入币种进行平衡。请检查日记帐分录行中输入的金额。 英文报错:The subledger journal entry does not balance i…

电机专用32位MCU PY32MD310,Arm® Cortex-M0+内核

PY32MD310是一颗专为电机控制设计的MCU&#xff0c;非常适合用做三相/单相 BLDC/PMSM 的主控芯片。芯片采用了高性能的 32 位 ARM Cortex-M0 内核&#xff0c;QFN32封装。内置最大 64 Kbytes flash 和 8 Kbytes SRAM 存储器&#xff0c;最高48 MHz工作频率&#xff0c;多达 16 …