1

以下は、いくつかのクラス継承を実践するための本からの演習です。しかし、問題はクライアントにあり、クラスの設計にはありません。(BaseCore、baseDMA、lacksDMA、hasDMAはクラスBTWです)。

// usedma.cpp -- polymorphic example (compile with dma.cpp)

#include <iostream>
#include "dma.h" // includes <iostream>

const int ELEMENTS = 1;
const int LENGTH = 30;

int main()
{
    using std::cin;
    using std::cout;

    BaseCore *pArr[ELEMENTS];
    char tempDate[LENGTH];
    char kind;

    for (int i = 0; i < ELEMENTS; i++)
    {
        cout << "\nEntering data for element #" << i + 1 << "\n\n";
        cout << "Enter the date it was created: ";
        cin.getline(tempDate, LENGTH - 1);
        cout << "Enter 1 for baseDMA, 2 for lacksDMA, or 3 for hasDMA: ";
        while (cin >> kind && kind != '1' && kind != '2' && kind != '3')
            cout <<"Wrong data. Please, try again: ";
        while (cin.get() != '\n')
            continue;
        char tempLabel[LENGTH];
        int tempRating;
        cout << "Enter the label: ";
        cin.getline(tempLabel, LENGTH - 1);
        cout << "Enter the rating: ";
        cin >> tempRating;
        if (kind == '1') // baseDMA
            pArr[i] = new baseDMA(tempDate, tempLabel, tempRating);
        if (kind == '2') // lacksDMA
        {
            char tempColor[LENGTH];
            cout << "Enter the color: ";
            cin.getline(tempColor, LENGTH - 1);
            pArr[i] = new lacksDMA(tempDate, tempLabel, tempColor, tempRating);
        }
        if (kind == '3') // hasDMA
        {
            char tempStyle[LENGTH];
            cout << "Enter the style: ";
            cin.getline(tempStyle, LENGTH - 1);
            pArr[i] = new hasDMA(tempDate, tempLabel, tempStyle, tempRating);
        }
        while (cin.get() != '\n')
            continue;
    }

    cout << "\n";
    for (int i = 0; i < ELEMENTS; i++)
    {
        pArr[i]->View();
        cout << "\n";
    }
    cout << "Done.\n";

    std::cin.get();
    return 0;
}

サンプル実行:

要素#1のデータを入力する

作成日を入力してください:2012.01.01

baseDMAの場合は1、lacksDMAの場合は2、hasDMAの場合は3を入力します。2

ラベルを入力してください:lacksDMA

評価を入力してください:15

色を入力してください:青

作成日:2012.01.01

ラベル:DMAがありません

評価:15

色:

終わり。

Colorメンバーにヌル文字が割り当てられているようです。if (kind == '2')この動作は、ステートメントとステートメントの両方で発生しますif (kind == '3')(この場合はスタイルメンバーを使用)。

cin.get();cin.getline()の直前に置くと正常に機能しますが、プログラムに入力を要求させるために追加のキーを押す必要があります。

なぜこうなった?入力キューに保留中の「\n」がある場合、cin.getline()はそれを破棄し、変数に「\0」を入れます。これは理解できます。しかし、プログラムは色の入力を要求し、通常どおりに入力します。また、cin.get()を配置した場合、プログラムは実行中に余分なキーストロークを待つ必要はなく、余分な'\n'を取り除く必要があります。ここで何が欠けていますか?

4

2 に答える 2

5
cout << "Enter the rating: ";
        cin >> tempRating;

とは異なり、はストリームに末尾を残しistream::getline()ます。これにより、if ステートメントのいずれかの内部への次の呼び出しで空の入力が取得されます。operator>>\ngetline

制御フローがwhile (cin.get() != '\n')for ループの最後でステートメントに到達すると、ストリームは空になります。ストリームは入力を待っており、まだ色を入力しているように見えます。

cin.ignore()すぐに電話して、それはうまくいきます。

この種のバグは、color の入力ステートメントの直後に「debugging cout」を配置すると、すぐに明らかになることに注意してください。取得方法にはもう 1 つの問題がありますtempRating。「xy」などの無効な入力を入力すると、エラーフラグが設定されcin、プログラムは無限ループに入ります。入力操作が成功したかどうかを常に確認してください。

于 2012-08-29T13:22:25.287 に答える
1

cin.get(); を入れると cin.getline() の直前で正常に動作しますが、プログラムに入力を求めるために追加のキーを押す必要があります。

cin.get() を配置しないと、getline が空の文字になっているように思えます。次に、cin.get を配置すると、その空の文字が取得され、getline が正常に機能します。

しかし、何が起こっているのかを正確に確認するには、必ずデバッグに行く必要があります!

于 2012-08-29T13:16:49.427 に答える