C++学习笔记-------IO类(istream、ostream fstream stringstream、IOt条件状态、缓冲区刷新、文件打开模式、等)

C++ Primer学习笔记 专栏收录该内容
41 篇文章 1 订阅


C++支持不同种类的IO处理操作。

  • iostream处理控制台IO。
  • fstream处理文件文件IO。
  • stringstream完成内存string的IO。

下表是C++中的IO操作类的定义以及头文件。
在这里插入图片描述
为了支持宽字符的语言,标准库定义了一些类型来操纵wchar_t 类型的数据。宽字符类型和普通自行没有都定义在同一个头文件中,在普通类型的前面添加w就行了,如何cin 相应的宽字符类型就是wcin
我们在使用大多数的IO操作时是不需要考虑文件类型的,也就是说我们可以无差别的将IO操作应用于普通流、文件流、和string流,以及char或者宽字符。但是IO对象不能进行拷贝和赋值

1.IO条件状态

IO类定义了一些函数或者标志来指示IO是否正常或者出错。
下表是常用的IO条件状态。
在这里插入图片描述
例子:

int val;
cin>>val;

如果输入一个字符则以上IO操作将会出错,因为希望得到的是int而非char,一个流操作一旦发生错误则他的后续IO操作将无法进行。如何确定一个流操作是否正常?那就是将其作为条件判断。

while(cin>>word)
{
	//IO操作
}

但是,有时我们需要具体知道流IO具体发生的错误我们可以上表提供的操作判断,举例:

	int a;
    cin>>a;

    if (cin.fail())
    {
        cout << "输入错误!" << endl;
    }
    else if (cin.good())
    {
        cout << a << endl;
    }
    else if (cin.bad())
    {
        throw runtime_error("IO已经崩溃!");
    }

如果对于输入的不是int 的数据则会发生错误,程序会输出“输入错误”。如果程序奔溃则相应的bad()会返回true。

clear() 函数将所有的标志位恢复为初始状态,其有两个版本的重载,一个有参数一个无参数。有参数的重载只会将传入参数的标志位重置。

一般使用流之前会保存该流的属性,当使用完成后将该流恢复。

auto old=cin.rdstate();
cin.clear();//将所有的位标志置为初始化状态。
/*使用IO流操作*/
cin.setstate(old);

2.输出缓冲区

刷新输出缓冲区
刷新方式有三种,分别是endl、ends、flush;

cout<<"hello"<<endl;//附加换行并刷新缓冲区;
cout<<"hello"<<ends;//附加一个空字符并刷新缓冲区;
cout<<"hello"<<flush;//刷新缓冲区,不添加附加任何东西。

unitbuf、nonunitbuf操纵符
unitbuf将输出流设置位每次输出后自动执行flush刷新,nonunitbuf则是将输入流恢复到正常的刷新模式。

cout<<unitbuf;
/*进行输出操作*/
cout<<nonunitbuf;

关联输入输出流
当一个输入流被关联到一个输出流时任何试图输入流读数据的操作都会先刷新关联的输出流。便准库将cin和cout关联.。
tie()函数是有两个重载版本,未带参数的版本用于判断对象是否关联到输出流,如果有关联输出流则返回输出流对象指针,否则返回空指针。带参数的用于将一个输入流关联到输出流,如:x.tie(&o)

cin.tie(&cout);//cin关联到cout
ostream *old_tie=cin.tie(nullptr);//cin不在和任何输出流关联,返回指针为以前关联的输出流;
cin.tie(&cerr);//cin和cerr关联
cin.tie(old_tie);//cin恢复到以前的关联

3.文件IO流

头文件fstream定义了三个类型来支持文件IO:ifstream从一个文件读取数据,ofstream向一个文件写入数据,以及fstream可以读写给定文件。
fstream继承iostream,但是除了iostream的操作外,fstream还提供了其他的操作。
在这里插入图片描述文件的打开与关闭
文件的打开方式有两种,一种是利用构造函数在定义时直接输入文件,另一种则是利用open()函数

 ofstream out("F:\\test1.txt");//初始化时直接打开文件
 ifstream in;
 in.open("F:\\test.txt");//用open函数打开文件
 string temp;
 getline(in, temp);//读取文件test.txt的一行到temp
 out << temp;//将读取temp的输出到文件test1.txt
 in.close();//关闭文件
 out.close();

类ifstream继承来自istream,类ofstream继承来自ostream,由于c++的多态特性,可以用iostream类的指针或者引用来指向ifstream。

open()、close()
如果打开文件失败failbit会被置位,因此每次调用open()应该调用if检查。

if(in){
	//执行文件操作
}

一个文件流对象只能同时和一个文件相关联,因此用完用完文件后应该调用close()函数关闭文件,同时文件将不再和文件流关联。

当一个fstream对象被销毁时析构函数会自动调用close();

文件打开模式
在这里插入图片描述
文件的模式在文件的打开时或者定义对象初始化时指定,指定方式为如下:

fostream out("file",ofstream::out);//初始化时指定文件模式
fostream out1;
out1.opent("file1",ofstream::out);//调用open()时指定文件模式

指定文件的打开模式有以下限制:

  • out模式只能对应ofstream和fstream;
  • in模式只能对应ifstream和fstream;
  • trunc模式只能在out模式下设定
  • trunc模式没有被设定是才能设定app模式,app模式下文件为out模式(只能输出)
  • 默认情况的out会将文件截断,只有同时指定out和app或者out和in时文件才不会被截断。
  • ate和binary能和任何模式进行组合。
  • ifstream默认为in,ofstream默认为out,fstream默认两者同时打开。

注意:以默认的方式打开ofstream文件会数据会丢失,保留文件的唯一方式是显示指定app或者in模式

4.string流

istringstream从string读取数据,ostringstream向string写入数据,而stringstream可以进行读也可以写。同样stringstream都是继承自iostream的。stringstream的独特的方法:
在这里插入图片描述
istringstream可以将与其绑定的字符串以”单词“的形式读出:
例子:

string str = "this is a test for sstream";
istringstream word(str);
while (word >> str)
{
    cout << str << endl;
}

上述例子将会把字符串中的灭个单词打印出来。

stringstream常用操作

string str1=word.str();//无参数的str()返回word的拷贝字符串
word.str("this is a reset");//重置word的拷贝字符串,此时str()返回void

ostringstream可以将与其绑定的字符串以”单词“的形式写入到string流;

ostringstream o_word;
auto li = initializer_list<string>({"this ","is ","test"});

for (auto it = li.begin(); it != li.end(); it++)
{
   o_word << *it;
}
cout << o_word.str();

上述的程序将会打印”this is a test“到终端。
关于程序中的initializer_list 请参考:https://editor.csdn.net/md/?articleId=112553878

  • 1
    点赞
  • 0
    评论
  • 2
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值