C++ PRIMER 学习笔记 第八章

Posted on 2022-08-10 10:37  金色的省略号  阅读(24)  评论(0编辑  收藏  举报

  操纵符 是一个函数或一个对象,会影响流的状态并能用作输入或输出的运算符的 运算对象(操作数)a manipulator is a function or object that can be used as an operand to an input or output operator.

第8章 标准IO库

   8.1 面向对象的标准库

  sstream所定义的类型用于读写 存储在内存中 的string对象,如果函数有 基类的引用形参 时,可以给函数传递其派生类型的对象,IO类型通过继承关联,所以可以只编写一个函数,将它应用到三种类型的流上:控制台、磁盘文件或字符串流

  

  流类(stream class)读写的是由char类型组成的流,标准库还定义了一组相关的类型,支持wchar_t类型,每个类都加上w前缀,以此与char类型的版本区分,基于流的wchar_t类型的类和对象在iostream中定义,宽字符文件流类型在fstream中定义,宽字符stringstream在sstream中定义

  标准库类型不允许做复制或赋值操作:只有支持复制的元素类型可以存储在vector或其他容器类型里,不存在存储流对象的容器形参或返回类型也不能为流类型,如果需要传递或返回IO对象,必须传递或返回指向该对象的指针或引用  

  8.2 条件状态

  IO标准库管理一系列条件状态成员,来标记给定的IO对象是否处于可用状态,或者碰到了哪种特定的错误,流必须处于无错误状态,才能用于输入或输出,检测流是否可用的最简单的方法是检查其真值

  所有流对象都包含一个条件状态成员,由setstate和clear操作管理,这个状态成员为iostate类型,是由各个iostream类分别定义的机器相关的整形,该状态成员以二进制位的形式使用,每个IO类还定义了三个iostate类型的常量值,分别表示特定的位模式 (按位或操作使用其操作数的二进制位模式产生一个整形数值),badbit标志着系统级的故障,如无法恢复的读写错误

  流状态的查询和控制:

#include <iostream>
using namespace std;

int main()
{
    int ival;
    //循环不断读入cin,直到到达文件结束符或者发生不可恢复的读取错误为止
    while( cin>> ival, !cin.eof() ){
        if( cin.bad())                     //input stream is corrupted
            throw runtime_error("IO stream corrupted");
        if( cin.fail()){                   //bad input 
            cerr << "bad data, try again";
            cin.clear(istream::failbit);   //reset the stream
            continue;                      //get next input
        }
        cout << ival;
    }
    
    return 0;
}
View Code

  8.3 输出缓冲区的管理

  每个IO对象管理一个缓冲区,用于存储程序读写的数据,下面几种情况将导致缓冲区的内容被刷新,即写入到真实的输出设备或文件:1、程序正常结束;2、在一些不确定的时候,缓冲区可能已经满了,在这种情况下,缓冲区会在写下一个值之前刷新;3、用操纵符显式地刷新缓冲区,如:endl;4、在每次输出操作执行完后,用unitbuf操纵符设置流的内部状态,从而清空缓冲区;5、可将输出流与输入流关联起来,在这种情况下,在读输入流时,将刷新其关联的输出缓冲区

  8.4 文件的输入和输出

  fstream头文件定义了三种支持文件IO的类型:ifstream、ofstream、fstream

#include <iostream>
#include <fstream>  //ifstream ofstream
#include <string>   //string
using namespace std;

ifstream& open_file( ifstream& in, const string& file)
{
    in.close(); //不清楚流in的当前状态,首先调用close和clear将这个流设置为有效状态
    in.clear();
    in.open( file.c_str() ); //打开文件
    return in; //已经与指定文件绑定,或处于错误条件状态
}

int main()
{  
    ifstream in;  
    open_file( in, "d:/1.txt" ); //函数调用
    
    string line;
    while( in >> line)        //每次读取,空白符为结束标志
        cout << line << " ";
    /* while( getline(in,line) )
        cout << line << " "; */
    
    in.close();
    
    return 0;
}
View Code

  文件模式:in  out  app  ate  trunc  binary ,ate模式只在打开时有效(in 与 ate 合用,ios::ate | ios:: in),文件打开后将定位在文件尾,以out模式打开的文件会被清空:丢失该文件存储的所有数据,等效于同时指定了out和trunc模式

#include <iostream>
#include <fstream>  //ifstream ofstream
#include <string>   //string
using namespace std;

int main()
{  
    ofstream ofs;  
    ofs.open( "d:/1.txt", ofstream::app ); //文件模式 in out app ate trunc binary
    
    string line;
    while( getline(cin,line) ){
        ofs << line;
    }
    
    ofs.close();
    
    return 0;
}
View Code

  8.5 字符串流

  iostream标准库支持内存中的输入输出,只要将流与存储在程序内存中的string对象捆绑起来即可,标准库定义了三种类型的字符串流istringstream ostringstream stringstream 

#include <iostream>
#include <sstream>  //istringstream ostringstream stringstream(读写) 
#include <string>   //string
using namespace std;

int main()
{   //------------------写----------------------//
    string line;
    int val1 = 512, val2 = 1024;
    ostringstream format_message;                     //
    format_message << "val1: " << val1 << "\n"    
                   << "val2: " << val2 << "\n";   //将指定内容插入到ostringstream对象,重点在于int型值自动转换为等价的可打印字符串
    line = format_message.str(); //返回ostringstream对象format_message中存储的string类型对象
    cout << line;
    //------------------读-----------------------//
    int val3, val4;
    string dump;
    istringstream input_istring ( format_message.str()); //
    input_istring >> dump >> val3 >> dump >> val4;
    cout << val3 << " " << val4 << endl;
    
    return 0;
}
View Code
#include <iostream>
#include <sstream>  //istringstream ostringstream stringstream(读写) 
#include <string>   //string
using namespace std;

int main()
{
    string line = "123a 456b 789c", word;
    istringstream stream( line ); //istringstream由 istream 派生读 string
    while(stream >> word ){
        int x = atoi( word.c_str() );
        cout << x << endl;
    }
    return 0;
}
View Code