2012-09-11 11 views
14

C++でファイルIOを実行するために、ofstream、ifstream、およびfstreamクラスを使用します。C++ファイルストリームのオープンモードのあいまいさ

  • ofstreamの:Streamクラスファイル
  • はifstreamに書き込むために:読み取りとファイル

へ/から書き込むために、両方のStreamクラス:ファイルから

  • のfstreamを読み取るためにStreamクラスファイルをストリームオブジェクトに関連付ける処理は、「ファイルを開く」と呼ばれます。 ファイルを開く際に、ファイルを開くモードを指定することができます。 クエリはios::outios:inモードに関連しています。

    私はofstreamオブジェクトを作成し、ios::inモードでファイルを開くと、私は、ファイルに 書き込むことができていますが、その既に作成する場合にのみ(それはまだ存在していない場合ios::outモードファイルでも作成されます)。
    しかし、ifstreamオブジェクトを作成し、ios::outモードでファイルを開くと、ファイルから読み込むことができます。

    私の質問は、なぜこれらのモード(ios::in/ios::out)は、ストリームのタイプ(ifstream/ofstream)自体は、操作の種類(入力/出力)が行われているのように指定した場合、言語によって提供されているのですか?

    このあいまいな使い方(ios::outios::inofstreamifstream)が1の場合で動作し、他に(ファイルが既に存在していない場合にのみですが)失敗した。また、なぜ?

  • 答えて

    11

    ofstreamifstreamfstreamクラスは、1つのストリームのrdbuf()メンバー関数を介して取得することができしたっぱfilebuf、ハイレベルのインターフェースです。

    ofstreamのモードをmodeで開くと、標準では、mode | ios_base::outのように下線付きのストリームバッファが開きます。同様にifstreammode | ios_base::inを使用します。 fstreamは、modeパラメータをそのまま下線付きストリームバッファに渡します。

    何上記の意味は次のコードはまったく同じオープンフラグでファイル開くことです:あなたはf.rdbuf()g.rdbuf()h.rdbuf()とまったく同じことを行うと、すべてのことができ、これらの行の後

    fstream f("a.txt", ios_base::in | ios_base::out); 
    ifstream g("a.txt", ios_base::out); 
    ofstream h("a.txt", ios_base::in); 
    

    を3つは、Cのコールfopen("a.txt", "r+")でファイルをオープンした場合と同じように動作します。これは、読み取り/書き込みアクセス権を与え、ファイルを切り捨てず、ファイルが存在しなければ失敗します。

    私たちはなぜ3つの異なるクラスを持っていますか?すでに述べたように、これらは高水準のクラスであり、低レベルのストリームバッファーに対する高水準のインターフェースを提供します。考えられるのは、ifstreamには入力のメンバー関数(read()など)があり、ofstreamには出力のメンバー関数(write()など)があり、fstreamにはその両方があるという考えがあります。 gifstreamですが、我々はios_base::outでそれを開いていた、ので、

    g.write("abc", 3); // error: g does not have a write function 
    

    しかし、これは動作します:

    g.rdbuf()->sputn("abc", 3); // we still have write access 
    
    をたとえば、あなたがこれを行うことはできません
    0

    モードは入力/出力に限定されないためです。 ifstreamのコンストラクタは、例えば、次のようになります。

    explicit ifstream (const char * filename, ios_base::openmode mode = ios_base::in); 
    

    注デフォルト値はios_base::inあるので、あなたはそれを自分で指定する必要はありません。

    • appは(追加)各出力操作の前にストリームの最後にストリームの位置インジケータを設定します。ただし、modein/outに限定されるものではないあるが、含まれるストリーム・フラグをセットします。
    • ate(終了時)ストリームの位置インジケータをストリームの最後に設定します。
    • binary(バイナリ)ストリームをテキストではなくバイナリと見なします。
    • in(入力)ストリームに対する入力操作を許可します。
    • out(出力)ストリームに対する出力操作を許可します。
    • trunc(切り捨て)現在の内容は破棄されます。開封時に長さがゼロであると仮定します。
    関連する問題