C++のIOライブラリの概要と操作ノート


C++のIOライブラリの概要と操作ノート
  • CのIOライブラリの概要と操作ノート
  • IOクラス
  • IOクラス継承関係
  • 条件状態
  • 出力管理
  • ブラシバッファ
  • unitbufオペレータ
  • バインド入出力ストリームオブジェクト

  • ファイルIO
  • 初期化
  • ファイルモード
  • stringストリーム
  • CスタイルIO
  • まとめ

  • C++は2種類のIOライブラリを含み、1つはストリーム形式に基づくIOライブラリであり、もう1つはCスタイルのIO関数ライブラリであり、以下ではそれぞれC++のストリーム形式IOに重点を置くかを述べる.
    IOクラス
    IOクラス継承関係
    ストリームベースの入出力は、コンソールウィンドウ、ファイル、メモリのstringオブジェクトを含む抽象的な入出力デバイスの周りに組織され、これらのクラスはテンプレート化されており、クラスの継承形式は次の通りです.
    C++のIOクラス継承アーキテクチャ図
    上の継承関係図では、
    ios_baseはインタフェースクラスで、主にフォーマット記号と入出力異常を管理し、通常は直接操作しません.ベースクラスを使用する必要がある場合も使用します.
    basic_iosは、任意のストリーム操作を管理するために使用されます.ただし、日常的に使用する場合、上図のクラス名を直接使用するのではなく、別名で呼び出されます.別名の使い方は、wで始まるワイド文字タイプで使用されるコードに示されています.IOストリームの使用では、
    ベースクラスではこれらの関数がプライベート化されているため、コピー構造や付与文は使用できません.また、2つのライブラリiomanipとstdiostreamに注目する必要があります.前者は、CとC++を混合して使用するIOメカニズムをフォーマットするいくつかの操作を宣言します.
    /* Defined in header <ios> */
    typedef basic_ios<char>                 ios;
    typedef basic_ios<wchar_t>             wios;
    
    /* Defined in header <streambuf> */
    typedef basic_streambuf<char>     streambuf;
    typedef basic_streambuf<wchar_t> wstreambuf;
    /* Defined in header <fstream> */
    typedef basic_filebuf<char>         filebuf;
    typedef basic_filebuf<wchar_t>     wfilebuf;
    /* Defined in header <sstream> */
    typedef basic_stringbuf<char>     stringbuf;
    typedef basic_stringbuf<wchar_t> wstringbuf;
    
    /* Defined in header <istream> */
    typedef basic_istream<char>         istream;
    typedef basic_istream<wchar_t>     wistream;
    /* Defined in header <ostream> */
    typedef basic_ostream<char>         ostream;
    typedef basic_ostream<wchar_t>     wostream;
    /* Defined in header <istream> */
    typedef basic_iostream<char>       iostream;
    typedef basic_iostream<wchar_t>   wiostream;
    
    /* Defined in header <fstream> */
    typedef basic_ifstream<char>       ifstream;
    typedef basic_ifstream<wchar_t>   wifstream;
    typedef basic_ofstream<char>       ofstream;
    typedef basic_ofstream<wchar_t>   wofstream;
    typedef basic_fstream<char>         fstream;
    typedef basic_fstream<wchar_t>     wfstream;
    
    /* Defined in header <sstream> */
    typedef basic_istringstream<char>     istringstream;
    typedef basic_istringstream<wchar_t> wistringstream;
    typedef basic_ostringstream<char>     ostringstream;
    typedef basic_ostringstream<wchar_t> wostringstream;
    typedef basic_stringstream<char>       stringstream;
    typedef basic_stringstream<wchar_t>   wstringstream;

    私たちが普段最も接触しているのは、標準ライブラリで予め定義されているcin(wcin)、cout(wcout)、cerr(wcerr)、clog(clog)です.彼らはそれぞれ標準入力ストリーム、標準出力ストリーム、標準エラー出力ストリーム、標準ログ出力ストリームに対応していますが、rdbuf()メソッドを通じてこれらのストリームオブジェクトのバッファを変更したり、これらのストリームオブジェクトの標準機能を変更したりすることができます.注意cerrストリームにはバッファがありません.
    じょうけんじょうたい
    ストリームオブジェクトにおいて非常に重要な特性は条件状態であり、エラーが発生すると、ストリームオブジェクトのその後の操作が必ず失敗するため、ストリームオブジェクトの現在の状態と正常に動作するかどうかを知ることができます.すべてのストリームオブジェクトには、goodbit、badbit、eofbit、failbitの4つの条件状態があります.goodbitはストリームオブジェクトが正常であることを表し、badbitはストリームオブジェクトがクラッシュしたことを表し、回復できないことを表し、eofbitはストリームオブジェクトがストリームの終了位置にあることを示し、failbitはあるIO操作が失敗したことを示しているが、このエラーは回復できる.また、eof()、fail()、bad()、good()、clear()、setstate()、rdstate()などの方法で条件状態を判断し、操作する方法も提供されている.これらの方法の使用方法をコードで説明します.
    #include<string>
    #include<sstream>
    #include<iostream>
    using namespace std;
    
    int main(int argc, char* argv[])
    {
        string obj{"just a test!"};
        stringstream ss(obj);
        stringstream::iostate state = ss.rdstate();     /*              */
        ss.setstate(state | stringstream::failbit);     /*       failbit   */
        string tmp;
        while(ss>>tmp)                                  /*       ,         */
        {
            cout<<tmp<<endl;
        }
        if(ss.fail())
            cout<<"true"<<endl;
    
        string obj2{"another test!"};
        ss.str(obj2);                                    /*        BUFFER */
        ss.clear();                                      /*         */
        while(ss>>tmp)
        {
            cout<<tmp<<endl;
        }
        if(ss.eof())
            cout<<"true"<<endl;
    
        return 0;
    }

    結果:true another test!true
    次に、条件状態ビットと条件判断方法の関係を表で説明します.
    ios_base::iostate flags
    basic_ios accessors
    eofbit
    failbit
    badbit
    good()
    fail()
    bad()
    eof()
    operator bool
    operator !
    false
    false
    false
    true
    false
    false
    false
    true
    false
    false
    false
    true
    false
    true
    true
    false
    false
    true
    false
    true
    false
    false
    true
    false
    false
    false
    true
    false
    true
    true
    false
    true
    true
    false
    false
    true
    true
    false
    false
    false
    false
    false
    true
    true
    false
    true
    false
    true
    false
    true
    true
    true
    false
    true
    true
    true
    false
    false
    true
    false
    true
    false
    true
    true
    true
    true
    false
    true
    true
    true
    false
    true
    fail()メソッドとoperatorが表示されます!作用は等価であり,operator boolはfail()法の作用とは逆である.
    しゅつりょくかんり
    各出力ストリームオブジェクトはバッファを管理します.これはIO操作が非常に時間がかかるためです.このバッファが存在するため、ストリームオブジェクトは出力をバッファに保存し、以下の条件の1つが満たされるまで一緒に出力します.私たちの日常的なプログラミングでは、必要に応じて出力タイミングを管理する必要があります.従って、以下の条件に対して、出力を管理する方法がいくつか提供される.
  • プログラムは正常に完了し、例えばreturn;
  • バッファがいっぱいです.
  • オペレータendlが顕著に現れる.
  • オペレータunitbufを使用してバッファの中間状態を空に設定します.
  • 出力ストリームオブジェクトは、他の入力または出力ストリームオブジェクトとバインドされている.

  • 前の2つの条件はプログラム自身が判断し、次の3つの条件はプログラム作成プロセスで出力を管理することができる.
    ブラシバッファ
    cout<<"hi!"<<endl;         /*       */
    cout<<"hi!"<<flush;        /*       */
    cout<<"hi!"<<ends;         /*     null */
    cout.flush();

    unitbufオペレータ
    cout<<unitbuf;         /*            */
    cout<<nounitbuf;       /*      */

    入力と出力ストリームオブジェクトのバインド
    cin.tie(&cout);         /*               ,              */
                            /*               ,                 */

    ファイルIO
    初期化
    ファイルストリームオブジェクトには2つの初期化形式があります.1つ目は、コンストラクション関数を使用して、1つのファイルストリームオブジェクトをインスタンス化するときに直接ファイル名を割り当て、2つ目はopen()メソッドを使用して、1つのファイルストリームオブジェクトをインスタンス化した後にopen()メソッドを明示的に呼び出してファイルを開き、ファイルストリームオブジェクトは役割ドメインの終了時に自動的にコンストラクション関数を呼び出してファイルを解放します.ただし、役割ドメイン内で同じファイルを操作する別のファイルストリームオブジェクトが必要な場合は、最初のファイルストリームオブジェクトがclose()メソッドを明示的に呼び出してファイルを解放する必要があり、1つのファイルが同じ時間に1つのファイルストリームオブジェクトにのみアクセスできます.利用is_Open()メソッドは、ファイルストリームオブジェクトがファイルを開いているかどうかを判断します.
    #include <string>
    #include <fstream>
    #include <iostream>
    using namespace std;
    
    int main(int argc, char* argv[])
    {
        string filename = "example.123";
        fstream fs;
        fs.open(filename);
        if(!fs.is_open())                      /*         */
        {
           fs.clear();                         /*        */
           fs.open(filename, ios::out);        /*      */
           fs.close();
           fs.open(filename);
        }
    
        cout<<boolalpha;
        cout<<"fs.is_open() = "<<fs.is_open()<<endl;
        cout<<"fs.good() = "<<fs.good()<<endl;
    }

    結果:true true
    ファイルモード
    オンモード、相または演算可能
    意味
    in
    入力用
    out
    出力用、デフォルトはtrunc形式
    app
    追加、毎回、truncと反発するために使用
    ate
    開くと末尾に配置され、一度、単独で使用できません.
    trunc
    開くときにファイルの内容を破棄
    binary
    バイナリ形式、単独では使用できません
    string流
    stringストリームオブジェクトは、stringオブジェクトをバッファとして使用し、string内のコンテンツを他のタイプのオブジェクトに出力または入力できます.stringストリームオブジェクトは、インスタンス化時に1つのstringオブジェクトで構築することも、インスタンス化後にstr()メソッドで新しいstringオブジェクトをロードすることもできます.他の操作方法はファイルストリームオブジェクトと似ています.stringストリームオブジェクトの利点の1つは、タイプ変換を自動的に行うことです.
    #include<string>
    #include<sstream>
    using namespace std;
    
    int main(int argc, char* argv[])
    {
        string str{"123 5.89 false"};
        stringstream ss(str);
        int inttmp;
        double doubletmp;
        bool booltmp;
        ss>>inttmp;
        ss>>doubletmp;
        ss>>booltmp;
        cout<<inttmp<<'\t'<<doubletmp<<'\t'<<booltmp<<endl;
        return 0;
    }

    結果:123 5.89 0
    CスタイルIO
    CスタイルのIOは、FILE構造ポインタが指すファイルまたはオブジェクトを操作する一連の関数で構成され、この一連の関数はで宣言されている.ファイルアクセスクラスfopen、freopen、fclose、fflush、fwide、setbuf、setvbuf
    直接入出力クラスfread、fwrite
    非フォーマット入出力バイト/文字列fgetc/getc、fgets、fputc/putc、fputs、getchar、gets、putchar、putchar、puts、ungetc
    フォーマット入出力バイト/文字列scanf/fscanf/fscanf、vscanf/vfscanf/vscanf、printf/fprintf/sprintf/snprintf、vprintf/vfprintf/vsprintf/vsprintf/vsnprintf
    ファイル位置ftell、fgetpos、fseek、fsetpos、rewind
    エラー処理clearerr,feof,ferror,perror
    ファイル操作remove、rename、tmpfile、tmpname
    まとめ
  • iostreamクラスはコンソールのIO
  • に処理される
  • fstreamクラス処理ファイルのIO
  • stringstreamクラスは、メモリ内のstringオブジェクトのIO
  • に処理される.
    fstreamクラスとstringstreamクラスはiostreamクラス、ifstreamクラスとistringstreamクラスはistreamクラス、ofstreamクラスとostringstreamクラスはostreamクラスに継承されます.各IOオブジェクトには、実行可能か否かを示す一連の条件状態がある.エラーが発生した場合、問題が解決されるまでストリームオブジェクトにさらなる入力または出力はなく、ステータスがリセットされます.また、標準IOライブラリでは、これらのステータスを設定およびテストするための一連の関数も提供されています.
    PS:本明細書にはIOオペレータがあり、ストリームオブジェクトのバッファリングおよびより具体的なIOストリームオブジェクトの方法は関連していないため、本明細書では補足と拡張を継続します.本文の不足点と筆者の知識の欠陥による誤りは読者に指摘してもらって、ありがとうございます