6.7 输入输出流

news2024/11/28 6:51:45

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

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

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类型的数据。

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

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

相关文章

安装ps提示vcruntime140.dll丢失的解决方法,总结5种解决方法

在电脑使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“找不到vcruntime140.dll”。这个问题可能会导致程序无法正常启动或运行&#xff0c;因此了解其原因和解决方法是非常必要的。小编将从多个方面对“找不到vcruntime140.dll”这一问题进行详细…

端午与高考的交汇点:家的温暖与梦想的起点

当端午节的粽香弥漫在街头巷尾&#xff0c;高考的脚步也悄然而至。这两个看似毫无关联的时刻&#xff0c;却在每年的六月&#xff0c;奇妙地交汇在一起&#xff0c;为我们带来了一段特别的记忆。这不仅是家的温暖与梦想的起点相遇的时刻&#xff0c;更是传统文化与现代追求共融…

用户输入表格数据设计(XPTable控件使用说明九)

XP Table控件可以编辑数据&#xff0c;程序也可以使用编辑后的数据&#xff0c;但是程序新建时又从初始化数据到模型到显示&#xff0c;这两步有点绕&#xff0c;做了一个实例来说明这块内容。 流程1&#xff1a;初始化数据--> model--> UI show 流程2&#xff1a;UI--…

【面试官】知道synchronized锁升级吗

一座绵延在水上的美术馆——白鹭湾巧克力美术馆。它漂浮于绿水之上&#xff0c;宛如一条丝带轻盈地伸向远方 文章目录 可重入锁synchronized实现原理 synchronized缺点保存线程状态锁升级锁升级优缺点 1. 可重入锁 面试官&#xff1a;知道可重入锁有哪些吗? 可重入意味着获取…

【Git】之 【Bug】clone 克隆失败 过早的文件结束符

问题 解决 参考&#xff1a;git clone报错 过早结束问题解决方法 git config --global http.lowSpeedLimit 0 git config --global http.lowSpeedTime 999999 git config --global http.postBuffer 10024288000 git config --list

wireshark 标记自己想要的数据包

1:点击视图 2:点击视图-着色规则 点击新增一行,双击名称-进行编辑 过滤器规则-编辑自己想要看到的 点击前景-选择凸出显示颜色 点击背景--选择凸出显示颜色 点击确定按钮

LDR6020一拖二快充线:高效充电的新选择

LDR6020一拖二快充线&#xff1a;高效充电的新选择 随着移动设备的普及和功能的日益增强&#xff0c;电池续航成为了用户关注的重点之一。为了满足用户对于快速充电的需求&#xff0c;各大厂商纷纷推出了各种快充技术和产品。在这个背景下&#xff0c;LDR6020一拖二快充线凭借…

PowerDesigner导入Excel模板生成数据表

PowerDesigner导入Excel模板生成数据表 1.准备好需要导入的Excel表结构数据,模板内容如下图所示 2.打开PowerDesigner,新建一个physical data model文件,填入文件名称,选择数据库类型 3.点击Tools|Execute Commands|Edit/Run Script菜单或按下快捷键Ctrl Shift X打开脚本窗口…

台湾合泰原装BS66F360 封装LQFP-44 电容触摸按键 AD+LED增强型触控

BS66F360是一款由Holtek Semiconductor Inc.生产的微控制器&#xff08;microcontroller&#xff09;&#xff0c;具有触摸检测和LED驱动功能。其应用领域广泛&#xff0c;包括但不限于以下几个方面&#xff1a; 1. 触摸按键应用&#xff1a;BS66F360内置了触摸按键检测功能&am…

记一个ESP12-F芯片的坑

这两个都叫ESP-12F从外观上很难区分他们的差别&#xff0c;甚至背面的引脚都是一样的 这个单独的芯片就是从板子上拆下来的&#xff0c;使用这颗芯片按住FLASH按键LED灯会亮&#xff0c;很离谱&#xff0c;led灯的引脚是GPIO2 flash引脚是GPIO0&#xff0c;他们之间的内部封装…

matplotlib 动态显示训练过程中的数据和模型的决策边界

文章目录 Github官网文档简介动态显示训练过程中的数据和模型的决策边界安装源码 Github https://github.com/matplotlib/matplotlib 官网 https://matplotlib.org/stable/ 文档 https://matplotlib.org/stable/api/index.html 简介 matplotlib 是 Python 中最常用的绘图…

el-table合计行前置在首行,自定义合计行方法

背景 el-table原生合计行是在标签内增加show-summary属性&#xff0c;在表尾实现设计合计&#xff0c;且只对表格当前页面显示的列数据进行合计。element-UI效果如下图所示。 现要求在首行显示合计行&#xff0c;并自定义合计逻辑实现如下效果。 图示表格中&#xff0c;成本…

数据结构--线性表和串

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

AGP4+ 打包运行闪退,AGP7+ 正常(has code but is marked native or abstract)

问题 安装应用&#xff0c;点击图标启动立马闪退&#xff01; 诡异的闪退&#xff1a;AGP4 打包运行闪退&#xff0c;AGP7 正常 unity 导出的 Android 日志两个主要点&#xff1a; com.android.boot.App 是 Android 的 application 子类&#xff0c;程序入口 java.lang.Class…

网站开发需要用到哪些技术

网站开发涉及到多种技术&#xff0c;因为它需要前端和后端和数据库。 1.前端设计 在开发网站前端之前&#xff0c;需要提前设计前端的样子&#xff0c;这个时候就需要用到ps设计技术&#xff0c;美工技术&#xff0c;这个需要专业的知识储备才能把它做的更好&#xff0c…

若依项目部署(Linux2.0)

解压jdk tar -zxvf jdk-8u151-linux-x64.tar.gz 配置Java环境变量&#xff1a; vim /etc/profile export JAVA_HOME/root/soft/jdk1.8.0_151 export JRE_HOME${JAVA_HOME}/jre export CLASSPATH.:${JAVA_HOME}/lib:${JRE_HOME}/lib export PATH${JAVA_HOME}/bin:$PATH 设置环境…

vscode中jupyter notebook执行bash命令,乱码解决方法

问题描述 使用vscode中使用jupyter notebook执行bash命令时,不管是中文还是英文,输出均是乱码 但是使用vscode的terminal执行同样的命令又没有问题,系统自带的cmd也没有问题。 最终解决后的效果如下: ## 问题分析 默认vscode会选择使用cmd执行shell, 但是通过vscode的设…

路由器作为网络扩展器——设置桥接、路由模式

下面提到的路由器都是家用路由器 一、有线桥接(交换模式) 1.连接示意图 (副路由器只看交换模式部分) 副路由器充当交换机的角色 二、无线桥接(与有线类似) &#xff08;副路由器的无线信号 连接 主路由器的无线信号&#xff09; 三、路由模式 1.连接示意图 (副路由器只看…

neo4j入门并使用案例说明

1、neo4j是什么 Neo4j是一个高性能的NoSQL图形数据库&#xff0c;它将结构化数据存储在网络&#xff08;在数学角度称为图&#xff09;上&#xff0c;而不是传统的表中。Neo4j是一个嵌入式的、基于磁盘的、具备完全的事务特性的Java持久化引擎。它因其高性能、轻量级、易嵌入和…

STM32项目分享:智能台灯系统

目录 一、前言 二、项目简介 1.功能详解 2.主要器件 三、原理图设计 四、PCB硬件设计 1.PCB图 2.PCB板及元器件图 五、程序设计 六、实验效果 七、资料内容 项目分享 一、前言 项目成品图片&#xff1a; 哔哩哔哩视频链接&#xff1a; https://www.bilibili.c…