33

重複の可能性:
getline() のヘルプが必要

getline()いくつかの入力の後に使用すると、機能しません。

#include<iostream>
using namespace std;

main()
{
string date,time;
char journal[23];


cout<<"Date:\t";
cin>>date;
cout<<"Time:\t";
cin>>time;

cout<<"Journal Entry:\t";
cin.getline(journal,23);


cout<<endl;
system("pause");
}

getline()入力の上で使用するかのように、それは機能します

cout<<"Journal Entry:\t";
cin.getline(journal,23);
cout<<"Date:\t";
cin>>date;
cout<<"Time:\t";
cin>>time;

その理由は何ですか?

4

3 に答える 3

65

(n - 1) 文字が抽出されるか、区切り文字 (このパラメーターが指定されている場合は区切り文字、指定されていない場合は '\n') が見つかるまで、文字が抽出されます。入力シーケンスでファイルの最後に達した場合、または入力操作中にエラーが発生した場合にも、抽出は停止します。

入力から読み取るとcin.getline()、入力ストリームに改行文字が残っているため、c-string は読み取られません。cin.ignore()呼び出す前に使用しgetline()ます。

cout<<"Journal Entry:\t";
cin.ignore();
cin.getline(journal,23);
于 2012-10-02T13:44:54.337 に答える
10

@DavidHammenが言ったことに追加する:

抽出操作では、末尾の'\n'文字がストリームに残ります。一方、istream::getline()それを破棄します。getlineしたがって、抽出演算子の後に呼び出す'\n'と、最初の文字が検出され、そこで読み取りが停止します。

getline呼び出し抽出の前にこれを置きます:

cin.ignore()

入力を取得するより堅牢な方法は、次のようになります。

while (true) {

    cout<<"Time:\t";
    if (cin>>time) {
        cin.ignore();  // discard the trailing '\n'
        break;
    } else {
        // ignore everything or to the first '\n', whichever comes first
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
        cin.clear();  // clear the error flags
        cout << "Invalid input, try again.\n";
    }
}
于 2012-10-02T13:45:29.667 に答える
2

ストリームのステータスをチェックしていません。std::cinストリーム抽出演算子 ( operator>>) は失敗する可能性があります。その場合、ストリームは「不良」としてマークされます ( failbitbadbit、またはeofbitが設定されます)。「不良」になると、ステータスをクリアしない限り、そのストリームでの後続のストリーム抽出はすべて失敗します。

偏執狂的なプログラマになることを学びましょう。これらの書式付き入力操作のステータスを常に確認してください。たとえば、例外をスローしたり、エラー メッセージを出力して終了したりできます。すべきでないことの 1 つは、それが機能したと単純に想定することです。

于 2012-10-02T13:40:21.583 に答える