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

 更新时间:2021年07月23日 08:55:10   作者:HickeyZhang  
IO的设备可以是文件、控制台、string。c++主要定义了三种IO类型,分别被包含在iostream、fstream、sstream头文件中,本文给大家分享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流内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++程序检测内存泄漏的方法分享

    C++程序检测内存泄漏的方法分享

    这篇文章主要介绍了C++程序检测内存泄漏的方法分享,本文讲解了、对象计数、重载new和delete、Hook Windows系统API、使用DiagLeak检测等内容,需要的朋友可以参考下
    2015-03-03
  • C++ getline函数用法详解

    C++ getline函数用法详解

    这篇文章主要介绍了C++ getline函数用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • C/C++中使用列表框组件Qt ListWidget

    C/C++中使用列表框组件Qt ListWidget

    本文详细讲解了C/C++中使用列表框组件Qt ListWidget的方法,文中通过示例代码介绍的非常详细。对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-11-11
  • c语言冒泡排序法代码

    c语言冒泡排序法代码

    c语言冒泡排序法代码,这个是大家最早接触的算法吧,总在写 总在错,学习就是这么个过程, 温故才知新, 望自己谨记
    2013-02-02
  • 使用C++描绘心形

    使用C++描绘心形

    本文给大家分享的是一个使用c++绘制心形的代码,虽然情人节已经过去了,但是只要有心,天天都是情人节~~哈哈,让那些说程序猿都是木头的人去死吧。
    2015-03-03
  • C++构造函数的类型,浅拷贝与深拷贝详解

    C++构造函数的类型,浅拷贝与深拷贝详解

    这篇文章主要为大家详细介绍了C++构造函数的类型,浅拷贝与深拷贝,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • C++实现二分法求连续一元函数根

    C++实现二分法求连续一元函数根

    这篇文章主要为大家详细介绍了C++实现二分法求连续一元函数根,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-06-06
  • C语言 文件的打开与关闭详解及示例代码

    C语言 文件的打开与关闭详解及示例代码

    本文主要介绍C语言 文件的基础知识,这里整理了相关资料及示例代码,有兴趣的小伙伴可以参考下
    2016-08-08
  • 深入讲解C++数据类型转换的相关函数的知识

    深入讲解C++数据类型转换的相关函数的知识

    这篇文章主要介绍了深入讲解C++数据类型转换的相关函数的知识,包括类型转换运算符函数等内容,需要的朋友可以参考下
    2015-09-09
  • c语言实现输入一组数自动从大到小排列的实例代码

    c语言实现输入一组数自动从大到小排列的实例代码

    下面小编就为大家带来一篇c语言实现输入一组数自动从大到小排列的实例代码。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09

最新评论