c++中的基本IO类型详解

引言

c++不直接处理输入和输出,而是通过标准库中的类型处理IO。IO的设备可以是文件、控制台、string。c++主要定义了三种IO类型,分别被包含在iostreamfstreamsstream头文件中。

为了支持使用宽字符的语言,标准库定义了一组类型和对象操纵wchar_t类型的数据。

以下是这三种IO库类型以及头文件:

  • iostream头文件

istream(宽字符版本wistream),从流读取数据。
ostream (宽字符版本wostream),向流写入数据。
iostream(宽字符版本wiostream),读写流。

  • fstream头文件

ifstream(宽字符版本wifstream),从文件读取数据。
ofstream (宽字符版本wofstream),向文件写入数据。
fstream(宽字符版本wfstream),读写文件。

  • sstream头文件

istringstream(宽字符版本wistringstream),从string读取数据。
ostringstream (宽字符版本wostringstream),向string写入数据。
stringstream(宽字符版本wstringstream),读写string。

设备类型和字符大小不会影响我们要执行的IO操作。得益于继承机制,以上类型都可以使用>><<运算符以及getline()函数。

IO类型的通用特性

IO对象不能拷贝或赋值

istream is1,is2;
is1 = is2; //错误,流对象不能赋值
istream is3(is1); //错误,流对象不能拷贝

由于无法拷贝IO对象,因此不能将形参或返回类型设置为流类型。通常使用引用方式传递和返回流。但传递和返回的引用不能是const的,因为读写IO对象会改变IO对象的状态,也就是改变了IO对象。

IO对象的状态信息

IO类定义了一些函数和标志位,帮助我们检查和操纵流的状态:

  • strm::iostate是一种类型,这种类型就像一串二进制位串,每个二进制位串指出了流的状态。(strm为引言中的任意一种IO类型)。
  • eof()函数用于在IO对象上调用,如cin.eof()。如果流检测到eof(文件结束标志),该函数返回true。
  • fail()函数使用同上。如果流处于崩溃或IO操作失败的状态,返回true。
  • bad()函数使用同上。如果流处于崩溃状态,返回true。
  • good()函数使用同上。如果流处于有效状态,返回true。clear()函数使用同上。将IO对象中的所有条件状态为复位,流的状态变为有效状态,返回void。
  • setstate(flags),将IO对象的状态为按flags(类型为strm::iostate)指示的那样置位。
  • rdstate()函数用于在IO对象上调用,读取IO对象的状态位,返回类型为strm::iostate

一旦流发生错误,这个流上的后续IO操作都会失败,因此最好在使用流之前检查它是否处于良好状态。如

// 如果输入成功,流保持有效状态,条件为真
while(cin >> word){
    //读操作成功,其他操作。
}

输出缓冲

所有输出流都管理一个缓冲区,用来保存程序读写的数据。

cout << "Hello World!";

串"Hello World!"可能被立即打印出来,也可能被操作系统保存在缓冲区,随后打印。

以下原因可以刷新缓冲(即真正将数据输出到目标设备或文件中):

  • 程序正常结束,自动刷新。
  • 缓冲区满时,自动刷新。
  • 可以使用操作符endlflushends手动刷新缓冲区(只作用一次输出)。
cout << "1" << endl; //字符串后添加换行,然后刷新缓冲区
    cout << "2" << flush; //仅刷新缓冲区
    cout << "3" << ends;  //字符串后添加一个空字符,然后刷新缓冲区。

通过操作符unitbuf设置自动刷新。不同于endlflushends只作用于一次输出,设置了unitbuf后的输出流每输出一次都会自动刷新缓冲区。

cout << unitbuf;//下面的语句每执行一次输出,就刷新一次缓冲区。
    cout << "1"; //输出"1",自动刷新缓冲区
    cout << "2"; //输出"2",自动刷新缓冲区
    cout << "3"; //输出"3",自动刷新缓冲区
    cout << "4"; //输出"4",自动刷新缓冲区
    ...
    cout << "nounitbuf"; //回到流默认的缓冲方式

关联流。读写被关联的流时,关联到的流的缓冲区会被刷新(tie()函数括号里面的是关联到的流,调用tie()的流是被关联的流)。cout 和 cin默认关联在一起,使用cin读取数据时,cout的缓冲区被刷新。

 cout << "Fuck you!"; //没有指定操作符,cout默认不刷新,该语句执行完后"Fuck you!"可能立即被输出到屏幕,也可能稍后被输出。
    int i;
    cin >> i; //cout的缓冲区被刷新,此时"Fuck you!"一定已经真正输出(可能在之前就已经真正输出,此时刷新缓冲区等于什么都没做)。

使用tie()函数关联流和解除关联:

 cin.tie(&cout); //有参数的tie(),参数为指向流的指针,且指针不为空,此时建立关联。
    cin.tie(nullptr); //有参数的tie(),且指针为空,此时解除cin和其他流的关联。
    cin.tie(); //无参tie(),返回指向cin当前关联到的流的指针。

Note:

若程序崩溃即异常终止,输出缓冲区不会被刷新,换言之,缓冲区中的数据可能并没有真正被输出到文件或设备。

文件IO

创建文件流

前面所过,所有IO类型都可以使用>><<getline(),除此之外,文件IO还有一些特有的操作。

创建文件流:

 fstream fstrm1; //创建未绑定文件的文件流
    fstream fstrm2(s1); //创建绑定到指定文件s1的文件流(自动调用open())。s1是string或指向c风格字符串的指针。
    //fstream fstrm3(s2, mode); 与第二条语句类似,但指定打开文件的模式。

Note:

当一个fstream的作用域内的代码执行完毕,fstream关联的文件被自动关闭,即fstream对象被销毁时,close()会自动调用。

open和close

使用open打开文件,close关闭文件。对一个已经打开的文件调用open会失败,并且failbit被置位。

string file1 = "qq.dat";
    ifstream ifs;
    ifs.open(file1);
    //读取操作
    ifs.close();

文件模式mode

常用的文件模式mode如下:

  • in 只读方式打开文件
  • out 以写方式打开文件
  • app 每次写操作在文件末尾进行
  • ate 打开文件后立即定位到文件末尾
  • trunc 截断文件,即输出会覆盖文件中的原有数据。
  • binary 以二进制方式打开文件

同时指定多个模式时使用|分隔:

    ofstream ofs("file1", ofstream::out | ofstream::app);

Note:

out模式隐含trunc即覆盖原文件,若要在原文件末尾添加数据,则需要显式指明app模式。

若没有指定任何模式,则使用默认模式。

string IO

stringstream独有的操作如下:

 sstream strm;   //sstream为sstream头文件中定义的类型,具体可以是istringstream等。
    sstream strm(s); //建立一个sstream对象,保存字符串s的一个拷贝。
    strm.str(); //返回strm保存的string的拷贝。
    strm.str(s); //将string s拷贝到strm。

声明:
c++ Basic是对《C++ Primer 第五版》的个人总结与疑难解释,主要用于个人日后复习。
如果想要深入了解更多,请支持正版。

到此这篇关于c++中的基本IO的文章就介绍到这了,更多相关c++ io流内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++:IO类,文件输入输出,string流练习题

    目录 前面已经在用的IO库设施 IO类 IO对象不能拷贝或赋值 条件状态 管理输出缓冲 文件输入输出 fstream特有的操作 文件模式 string流 stringstream特有的操作 练习 练习1 练习2 练习3 练习4 练习5 练习6 练习7 练习8 练习9 总结 前面已经在用的IO库设施 istream:输入流类型,提供输入操作. ostream:输出流类型,提供输出操作 cin:一个istream对象,从标准输入读取数据. cout:一个ostream对象,向标准输出写入数据. ce

  • C++实现蓝桥杯竞赛题目---搭积木

    小明对搭积木非常感兴趣.他的积木都是同样大小的正立方体. 在搭积木时,小明选取 m 块积木作为地基,将他们在桌子上一字排开,中间不留空隙,并称其为第0层. 随后,小明可以在上面摆放第1层,第2层,--,最多摆放至第n层.摆放积木必须遵循三条规则 规则1:每块积木必须紧挨着放置在某一块积木的正上方,与其下一层的积木对齐: 规则2:同一层中的积木必须连续摆放,中间不能留有空隙: 规则3:小明不喜欢的位置不能放置积木. 其中,小明不喜欢的位置都被标在了图纸上.图纸共有n行,从下至上的每一行分别对应积木

  • 一道超经典的C++结构体的题目

    题目描述:有10个学生,每个学生的数据包括学号.姓名.英语.数学.物理三门课的成绩,从键盘输入10个学生数据,要求打印出3门课程的总平均成绩,以及最高分的学生的数据(包括学号,姓名,3门课的平均成绩,平均分数). c++代码: 复制代码 代码如下: #include<iostream>#include<string>using namespace std;struct Student{//声明结构体Student string num; string name; float eng

  • C++ LeeCode题目:比特位计数和买卖股票的最佳时机

    目录 一.比特位计数 一.题目 二.代码 二.买卖股票的最佳时机 一.题目 二.代码 总结 一.比特位计数 一.题目 二.代码 十进制转二进制-百度百科 class Solution { public: vector<int> countBits(int n) { vector<int> num; for(int i=0;i<=n;i++){//遍历[0,n],计算每个值对应二进制1的个数 num.push_back(countOne(i)); } return num; }

  • C++实现LeetCode数组练习题

    目录 1.存在重复元素 2.最大子序和 3.两数之和 4.合并两个有序数组 5.两个数组的交集II 6.买卖股票的最佳时机 7.杨辉三角 8.重塑矩阵 9.有效的数独 10.矩阵置零 总结 1.存在重复元素 排序数组,之后遍历是否有重复的元素 public boolean containsDuplicate(int[] nums) { Arrays.sort(nums); for(int i=1;i<nums.length;i++){ if(nums[i-1]==nums[i]){ return

  • c++中的基本IO类型详解

    引言 c++不直接处理输入和输出,而是通过标准库中的类型处理IO.IO的设备可以是文件.控制台.string.c++主要定义了三种IO类型,分别被包含在iostream.fstream.sstream头文件中. 为了支持使用宽字符的语言,标准库定义了一组类型和对象操纵wchar_t类型的数据. 以下是这三种IO库类型以及头文件: iostream头文件 istream(宽字符版本wistream),从流读取数据. ostream (宽字符版本wostream),向流写入数据. iostream(

  • Python中函数的参数类型详解

    目录 1.Python的函数参数的类型 2.Python的必传参数 3.关键字参数 4.默认参数 5.不定长参数 1.Python的函数参数的类型 必传参数:调用函数时必须传入的参数,函数定义时只定义参数名 关键字参数:传入时以函数的参数名值对的方式传入 默认参数:函数定义时为参数默认设置一个值,调用时不传输参数即以默认值处理 不定长参数:以*修饰或者**修饰的参数;*修饰的参数是一个元组(tuple),**修饰的参数必须是字典(dict),通常写作*args或者**args 2.Python的

  • C++中Covariant返回值类型详解

    目录 前言 什么是协变返回值类型(Covariant) 协变返回值类型(Covariant)的作用 前言 C++中当子类覆写(override)父类虚函数时,子类函数的返回值类型可以和父类函数的返回值类型不一致吗?先说结论:可以,但当且仅当它们的返回值类型是协变返回值类型(Covariant)时可以.C++中gcc从3.4开始支持这一特性. 什么是协变返回值类型(Covariant) 函数的协变返回值类型指的是子类中的成员函数的返回值类型不必严格等同与该函数所重写的父类中的函数的返回值类型,而可

  • MyBatis中传入参数parameterType类型详解

    前言 Mybatis的Mapper文件中的select.insert.update.delete元素中有一个parameterType属性,用于对应的mapper接口方法接受的参数类型.本文主要给大家介绍了关于MyBatis传入参数parameterType类型的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 1. MyBatis的传入参数parameterType类型分两种 1. 1. 基本数据类型:int,string,long,Date; 1. 2. 复杂数据类

  • php中的boolean(布尔)类型详解

    当转换为 boolean 时,以下值被认为是 FALSE: the 布尔值 FALSE 自身 the 整型值 0 (零) the 浮点型值 0.0 (零) 空 字符串, 以及 字符串 "0" 不包括任何元素的数组 不包括任何成员变量的对象(仅PHP 4.0 适用) 特殊类型 NULL (包括尚未设定的变量) 从没有任何标记(tags)的XML文档生成的SimpleXML 对象 所有其它值都被认为是 TRUE(包括任何资源). Warning -1 和其它非零值(不论正负)一样,被认为是

  • Java中文件的读写方法之IO流详解

    目录 1.File类 1.1File类概述和构造方法 1.2File类创建功能 1.3File类判断和获取功能 1.4File类删除功能 2.递归 2.1递归 2.2递归求阶乘 2.3递归遍历目录 3.IO流 3.1 IO流概述和分类 3.2字节流写数据 3.3字节流写数据的三种方式 3.4字节流写数据的两个小问题 3.5字节流写数据加异常处理 3.6字节流读数据(一次读一个字节数据) 3.7字节流复制文本文件 3.8字节流读数据(一次读一个字节数组数据) 3.9字节流复制图片 总结 1.Fil

  • MySQL binlog中的事件类型详解

    MySQL binlog记录的所有操作实际上都有对应的事件类型的,譬如STATEMENT格式中的DML操作对应的是QUERY_EVENT类型,ROW格式下的DML操作对应的是ROWS_EVENT类型. 首先,看看源码中定义的事件类型 源码位置:mysql-5.7.14/libbinlogevents/include/binlog_event.h enum Log_event_type { /** Every time you update this enum (when you add a ty

  • Python3中的bytes和str类型详解

    Python 3最重要的新特性之一是对字符串和二进制数据流做了明确的区分.文本总是Unicode,由str类型表示,二进制数据则由bytes类型表示.Python 3不会以任意隐式的方式混用str和bytes,你不能拼接字符串和字节流,也无法在字节流里搜索字符串(反之亦然),也不能将字符串传入参数为字节流的函数(反之亦然). 下面让我们深入分析一下二者的区别和联系. 编码发展的历史 在谈bytes和str之前,需要先说说关于编码是如何发展的.. 在计算机历史的早期,美国为代表的英语系国家主导了整

  • 对Python中画图时候的线类型详解

    在Python中用matplotlib画图的时候,为了区分曲线的类型,给曲线上面加一些标识或者颜色.以下是颜色和标识的汇总. 颜色(color 简写为 c): 蓝色: 'b' (blue) 绿色: 'g' (green) 红色: 'r' (red) 蓝绿色(墨绿色): 'c' (cyan) 红紫色(洋红): 'm' (magenta) 黄色: 'y' (yellow) 黑色: 'k' (black) 白色: 'w' (white) 灰度表示: e.g. 0.75 ([0,1]内任意浮点数) RG

  • Java 中的io模型详解

    1. BIO 我们先看一个 Java 例子: package cn.bridgeli.demo;   import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket;   /**  * @author bridgel

随机推荐