cin.getline() 奇怪的行为

Kur*_*dey 1 c++ queue user-input cin

以下是练习一些类继承的书中的练习。但问题出在客户端,而不是类设计。(BaseCore、baseDMA、缺乏DMA 和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;
}
Run Code Online (Sandbox Code Playgroud)

示例执行:

输入元素 #1 的数据

输入它的创建日期:2012.01.01

为 baseDMA 输入 1,为缺少 DMA 输入 2,或为 hasDMA 输入 3:2

输入标签:缺乏DMA

输入评分:15

输入颜色:蓝色

创建日期:2012.01.01

标签:缺少DMA

评分:15

颜色:

完毕。

似乎 Color 成员被分配了空字符。这种行为发生在if (kind == '2')andif (kind == '3')语句中(在这种情况下是样式成员)。

如果我cin.get();在 cin.getline() 之前放置一个它可以正常工作,但我必须按一个额外的键才能让程序要求输入。

为什么会这样?如果输入队列中有一个 '\n' 待处理,cin.getline() 将丢弃它并将 '\0' 放入变量中,我可以理解这一点。但是程序要求我输入颜色,让我正常输入。另外,如果我放了一个 cin.get(),那么程序不应该在执行中等待额外的击键,它应该去掉那个额外的 '\n'。我在这里缺少什么?

jro*_*rok 5

cout << "Enter the rating: ";
        cin >> tempRating;
Run Code Online (Sandbox Code Playgroud)

不同的是,istream::getline()operator>>离开尾随\n的流。它会导致对getline其中一个 if 语句的下一次调用获得空输入。

当控制流到达while (cin.get() != '\n')for 循环末尾的语句时,流为空- 它正在等待输入,并且看起来好像您仍在输入颜色。

之后立即打电话cin.ignore(),它会起作用。

请注意,如果您在颜色的输入语句之后立即放置“调试 cout”,则这种错误会立即显而易见。您获取tempRating. 如果输入无效输入,例如“xy”,错误标志将被设置,cin程序将进入无限循环。始终检查输入操作是否成功。