C++标准IO库梳理参考

一、io库的基本工具

• istream(输入流)类型,提供输入操作。
• ostream(输出流)类型,提供输出操作。
• cin:读入标准输入的 istream 对象。
• cout:写到标准输出的 ostream 对象。
• cerr:输出标准错误的 ostream 对象。cerr 常用于 程序错误信息。
• >> 操作符,用于从 istream 对象中读入输入。
• << 操作符,用于把输出写到 ostream 对象中。
• getline 函数,需要分别取 istream 类型和 string 类型的两个引用形 参,其功能是从 istream 对象读取一个单词(空格分隔),然后写入 string 对象中。

二、io库的条件状态控制

参照C++Primer中的函数表
这里写图片描述
这里写图片描述
上述反应了输入输出流的条件状态

//例子1
if(cin)
   //符合语法,表示可以用cin
while(cin>>n)
   //合法用法,检查了流的状态,如果输入成功条件为true
   //当出现系统级故障,读入无效数据或者遇到结束符eof时都会返回false

上面的例子1只能验证输入是否有效,而某些程序则需要更详细地访问或控制流的状态,此时,除了知道流处于错误状态外,还必须了解它遇到了哪种类型的错误。 这就用到了表中的类型和函数。
流的状态由 bad、fail、eof 和 good 操作提示。如果 bad、fail 或者 eof 中的任意一个为 true,则该流处于错误状态。如果这三个条件没有一个为 true,则 good 操作将返回 true。

#include<iostream>
#include<stdexcept>
using namespace std;
int main()
{
    int i;
    while (cin >> i, !cin.eof())//逗号操作符:首先计算它的每一个操作数,然后返回右边操作数作为整个操作的结果,cin.eof():如果到达终止符,返回true,这里表示没有到达终止符
    {
        if (cin.bad())
            throw runtime_error("IO stream Corrupted"); //系统出现故障,输入流崩溃
        if (cin.fail()) //输入类型不符合,可修正,所以continue
        {
            cerr << "bad data, try again" << endl;
            cin.clear();//重置cin但是不清除内容
            cin.sync();//清楚错误内容
            //cin.clear(istream::failbit); //此处为C++primer的写法,程序会陷入死循环,原因是cin.clear(istream::failbit);就是使failbit位设置为1,而把eofbit和badbit位清除为0。
            continue;
        }
        cout << i << endl; //输入成功,可以正确使用i
    }
}

下面是函数返回和调用istream的例子

#include<iostream>
#include<stdexcept>
using namespace std;
istream& fun(istream &i)
{
    int k;
    while (i>>k,!i.eof())
    {
        if (i.bad())
        {
            throw runtime_error("Corrupted");
        }
        if (i.fail())
        {
            cerr << "unexpected data,try again" << endl;
            i.clear();
            i.sync();
            continue;
        }
        cout << k << endl;
    }
    i.clear();
    return i;
}
int main()
{
    int k;
    fun(cin);
    system("pause");
}

输出缓冲区的刷新例子

cout << "zlk_flush" << flush; //直接刷新
cout << "zlk_ends" << ends; //空一格再刷新
cout << "zlk_endl" << endl; //空一行再刷新

三、iostream,fstream,sstream

1、iostream 为读写控制窗口
2、fstream为读写以命名文件
3、sstream为读写存储在内存的string对象
其类之间的派生关系为:
这里写图片描述

1、iostream:
istream类和ostream类以及iostream类不可自行创建对象,只能用iostream头文件里的全局变量cin 和cout 进行流输入和流输出。

2、fstream
文件流的使用例子:

#include<iostream>
#include<fstream>
#include<string>
#include<vector>
using namespace std;
int main()
{   
    string s;
    string file_in_str;
    string file_out_str;
    file_in_str = "E:\\testin.txt";
    string next_file = "E:\\testin2.txt";
    file_out_str = "E:\\testout.txt";
    //ifstream filein(file_in_str.c_str);  //另外一种打开方式
    //ofstream fileout(file_out_str.c_str); 
    ifstream filein;
    ofstream fileout;
    filein.open(file_in_str); //调用open方法绑定文件,当要给filein绑定新文件前要调用close()函数
    fileout.open(file_out_str); 
    //filein.close();
    if (!filein) //当open操作失败,filein为0
    {
        cerr << "错误:打开文件失败:" << file_in_str << endl;
    }
    vector<string> kk;
    while (getline(filein, s)) //读输入流的一个行
    //while (filein>>s) //读输入流的一个单词(遇到空格停止)
    {
        kk.push_back(s);
    }
    for (vector<string>::iterator i = kk.begin(); i < kk.end(); i++)
    {
        cout << *i << endl;
    }
    filein.close();//关闭文件
    filein.clear();//刷新缓冲区

}

上例中filein.open()的文件打开还支持文件打开方式,放到第二个参数就好,下面是打开方式列表:
这里写图片描述
这里写图片描述
还有可用的组合方式:
这里写图片描述

3、sstream
sstream的基本思路可以吧fstream中绑定的文件换成字符串,然后从字符串中读取。
stringstream的基本使用:

#include<iostream>
#include<sstream>
#include<string>
using namespace std;
int main()
{   
    string s1, s2;
    while (getline(cin, s1))
    {
        stringstream stri(s1); //给stingstream绑定一个string对象

        cout << stri.str() << endl; //stri.str()为string流所有内容(一直到结束符)
        while (stri >> s2)          //从string流s1中读单词,读到流末尾结束
        {
            cout << s2 << endl;
        }
    }
}

该类型流主要是为了类型转化,例如,有一个数值型数据集合,要获取它们的 string 表 示形式,或反之。详情请看下面例子:

#include<iostream>
#include<sstream>
#include<string>
using namespace std;
int main()
{   
    int a = 10, b = 24;
    string s="99";
    ostringstream oss;  
    oss.str(s);  //绑定字符串s
    oss << a << b;  //输入到字符串的时候不会从99的结尾接着输出,而是直接修改原来的数据
    string res = oss.str();  //将int型的a和b输入到字符串res中了
    cout << res << endl;//输出为1024
}

用istringstream从string中读取int(float也可以)

#include<iostream>
#include<sstream>
#include<string>
using namespace std;
int main()
{   
    string a = "1001 23";
    istringstream iss;
    iss.str(a);  //绑定字符串a
    cout << istr.str() << endl;
    int x, y, z;
    iss >> x >> y;
    z = x + y;
    cout << z << endl;  
}

ENDL;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章