2

私は非常に単純なコードを持っています。その機能は、プログラムがデータを読み取るファイルの名前を入力することです。入力ミスによりファイルが正しくない可能性があるため、以前の名前が無効な場合、コンソールは引き続きユーザーに名前を入力するように求めます。

問題は、最初の do-while ループは問題なく動作しますが、最初のループで最初にファイルの名前が正しく入力されていない場合、プログラムは 2 番目の while ループをスキップすることです。ただし、ファイルの名前が正しく入力されていれば、すべて正常に動作します。

なぜプログラムがこのように動作するのか不思議です。

あなたの助けとあなたの時間をありがとう!

#include<iostream>
#include<fstream>

using namespace std;

int main() {
    string context;
    int step=0,i=0;
    ifstream fin;

    do {
        string filename;
        cout << endl << "please type in the name of input file" << endl;
        cin >> filename;
        string filepath = "files/" + filename;
        cout << filepath << endl;
        fin.open( filepath.c_str() );
    } while( !fin.is_open() );

    while (getline(fin, context)){
        cout << context << endl;
        cout << "hello" << endl;
    }
    fin.close();
    return 0;
}
4

3 に答える 3

2

「ヒレ」の状態は、最初のトライで汚れてしまうのではないかと思います。fin.open() を呼び出す前に fin.clear() を呼び出そうとしないのはなぜですか。

于 2012-10-05T00:58:08.147 に答える
1

ifstream をクリアする必要があります。以前のファイル試行によって破損している可能性があります。

于 2012-10-05T00:59:59.017 に答える
1

基準から、

27.8.1.10
void open(const char* s, ios_base::openmode mode = ios_base::out);
コールrdbuf()->open(s,mode|out)。その関数がヌル ポインターを返す場合は、setstate(failbit) を呼び出します。311a

では、このノート 311a は何ですか?

311aオープンが成功しても、エラー状態は変わりません。

注記は規範的ではありませんが、正常なオープンが成功した場合にエラー状態に対して何を行うかについて、規範的なテキストはまったく何も述べていませんrdbuf->open()。注は、この非記述を明確にします。

結論:失敗した後に再呼び出しする場合clear、呼び出す前にファイル ストリームのステータス ビットを取得する必要があります。openopen

于 2012-10-05T01:07:57.750 に答える