cin.getline()的奇怪行为

cin.getline() strange behavior

本文关键字:getline cin      更新时间:2023-10-16

下面是一本书中练习类继承的练习。但问题出在客户端,而不是类设计。(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 << "nn";
        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:2 输入3

输入标签:lacksDMA

输入评级:15

输入颜色:蓝色

创建日期:2012.01.01

标签:lacksDMA

评级:15

颜色:

完成。

看起来Color成员被分配了空字符。这种行为发生在if (kind == '2')if (kind == '3')语句内部(在本例中为样式成员)。

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

为什么会发生这种情况?如果输入队列中有一个"\n"挂起,cin.getline()会丢弃它,并将"\0"放入变量中,我可以理解这一点。但是程序要求我输入颜色,让我正常输入。此外,如果我放了一个cin.get(),那么程序不应该在执行中等待一个额外的键笔划,它只应该去掉那个额外的'\n'。我在这里错过了什么?

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

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

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

之后立即致电cin.ignore(),它就会工作。

请注意,如果在颜色的输入语句后面加上"debugging cout",那么这种错误就会立即显现出来。获取tempRating的方式还有一个问题。如果输入无效的输入,比如"xy",则错误标志将在cin上设置,程序将进入无限循环。始终检查输入操作是否成功。

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

在我看来,当你不放cin.get()时,你的getline会得到一个空字符。然后,当你放cin.get时,你会得到一个空字符,你的getline工作得很好。。

但您绝对应该进行调试,看看到底发生了什么!