为什么我的程序第一次接受值并在下次运行时跳过我的第一个cin.getline()?

时间:2015-01-31 14:49:30

标签: pointers function-pointers

嗨,大家好我是指针新手,只是通过在线问题这样做。我的代码运行并且符合要求。 我很好奇我做错了什么让我的程序第一次运行正常然后在第二次运行不正确...第三等等。请指教!!提前致谢! 这是代码:

void continueProg(char& cont)
{
    cout << "Continue (Y/N)?: ";
    cin >> cont;
    if(cont=='y'||cont=='Y')
    {
        cont = 'Y';
    }
    else if((cont=='n')||(cont=='N'))
    {
        cont = 'n';
    }
    else
    {
        cout << "Please enter valid alaphelbet!\n";
        continueProg(cont);
    }
}

1 个答案:

答案 0 :(得分:1)

这是错误的:

UserEWord.W1=new char;
...
cin.getline(UserEWord.W1,'\n');

cin的类型为std::istream,因此您实际调用的方法为std::istream::getline()

从文档中可以看出,第一个参数必须是指向(应该是)字符的数组的指针,第二个参数n必须是允许方法写入的数组(包括终止NUL)。可选的第三个参数是char分隔符,顺便提一下,如果省略它,则默认为换行符('\n')。

您为W1(和W2)分配了一个字符,这意味着缓冲区中只有一个字符的空间。您在'\n'的调用中将n作为getline()传递,您显然希望将其作为分隔符。但最终结果是char值(10)将被视为缓冲区的大小,这太大了。任何非空输入都会溢出缓冲区,导致未定义的行为。

这里存在第二个问题,这是您确切问题的答案:

void continueProg(char& cont)
{
    cout << "Continue (Y/N)?: ";
    cin >> cont;
    if(cont=='y'||cont=='Y')

在这里,您将输入的单个字符串流式传输到cont,因为cont只是一个字符。但是,用户几乎肯定会输入的不仅仅是单个字符,至少由于他/她按下输入时发送的终止换行符。额外的未读输入将保留在系统的输入缓冲区中,直到您的程序再次尝试从cin读取输入,这发生在我上面引用的getline()呼叫中。因此,未读取的输入最终将被读取,直到未读的换行,这就是为什么程序在第一次之后的所有迭代都会跳过读取单词1的原因。

为了解决上述两个问题,我建议使用全局std::getline()功能,它允许您直接读取std::string,保证您获得完整的行,没有大小限制。例如:

std::string input;
std::getline(std::cin, input );

编辑:在回复您的评论时,不,您不能这样做。 std::string类型是C ++标准库提供的容器类,与语言的本地char / char*类型完全不同。您通常不能在需要另一个的地方直接使用一个(尽管应该提到您始终可以传递const char*char* std::stringconst std::string& IN参数预期,将调用隐式conversion constructorconst char*char*转换为const std::string&,但这仅适用于IN参数,而不是OUT参数,因为我们有这里有std::getline(),它采用非const std::string&(并且还应该提到,如果你有std::string,const或不是const,你可以调用{{3} }方法,以获得指向内容的const char*

如果你真的想坚持使用char的数组,那么要解决第一个问题,你必须做这样的事情:

#define MAX 100
...
UserEWord.W1=new char [MAX]; // allocate an array of MAX chars
...
cin.getline(UserEWord.W1,MAX);

要解决第二个问题,你可以使用cin.ignore();作为以赛亚书建议:

void continueProg(char& cont)
{
    cout << "Continue (Y/N)?: ";
    cin >> cont;
    cin.ignore(numeric_limits<streamsize>::max(),'\n'); // requires #include <limits>
    if(cont=='y'||cont=='Y')