cin.getline()奇怪的行为

时间:2012-08-29 12:52:20

标签: 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;
}

示例执行:

  

输入元素#1的数据

     

输入创建日期:2012.01.01

     

输入1表示baseDMA,输入2表示lacksDMA,输入3表示hasDMA:2

     

输入标签:lacksDMA

     

输入评分:15

     

输入颜色:蓝色

     

创建日期:2012.01.01

     

标签:lacksDMA

     

评分:15

     

颜色

     

完成。

似乎为Color成员分配了空字符。此行为发生在if (kind == '2')if (kind == '3')语句中(在本例中为样式成员)。

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

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

2 个答案:

答案 0 :(得分:4)

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

istream::getline()不同,operator>>会在流中留下尾随\n。它导致在你的一个if语句中对getline进行下一次调用以获得空输入。

当控制流在for循环结束时达到while (cin.get() != '\n')语句时,流为空 - 它正在等待输入,看起来好像你还在输入颜色。

立即拨打cin.ignore(),然后就可以了。

请注意,如果您在输入语句后面放置一个“调试cout”,那么这种错误就会很明显。获得tempRating的方式还有一个问题。如果输入无效输入,例如“xy”,则会在cin上设置错误标志,程序将进入无限循环。始终检查输入操作是否成功。

答案 1 :(得分:0)

  

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

在我看来,当你没有放入cin.get()时,你的getline会得到一个空字符。然后,当你输入cin.get时,你得到那个空字符,你的getline工作正常......

但你绝对应该进行调试才能确切了解发生了什么!