【问题标题】:While loop skips cin.getline() for C-stringWhile 循环跳过 C 字符串的 cin.getline()
【发布时间】:2020-01-26 13:00:21
【问题描述】:

我想使用 while 循环反复询问用户输入一行 cin.getline() 并将输入存储为 C 字符串。

#include <iostream>
int main()
{
    const int N = 3;
    char arr[N + 1] = {};
    while (true)
    {
        std::cout << "Please enter " << N << " characters: ";
        std::cin.getline(arr, N + 1, '\n');
    }
}

如果用户键入abc,则arr 包含abc\0,并且在下一个循环中,它会按预期暂停下一行输入。

如果用户键入abcd,则arr 仍包含abc\0,但在下一个循环中,第一个元素a 更改为\0 和程序再也不会为下一行输入暂停。它只是一遍又一遍地打印出“请输入 3 个字符:”。为什么?无论输入如何,我怎样才能让它每次都暂停?

已解决

感谢 Olaf 指出我需要重置故障位。

#include <iostream>
#include <limits>
using namespace std;
int main()
{
    const int N = 3;
    char arr[N + 1] = {'\0'};
    while (true)
    {
        cout << "Please enter " << N << " characters: ";
        cin.getline(arr, N + 1, '\n');
        if (cin.fail())
        {
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
        }
    }
}

【问题讨论】:

    标签: c++ cin getline c-strings


    【解决方案1】:

    发生这种情况,因为设置了failbit,请参阅std::basic_istream::getline

    表现为 UnformattedInputFunction。构造并检查哨兵对象后,从 *this 中提取字符并将它们存储在第一个元素由 s 指向的数组的连续位置中,直到发生以下任何一种情况(按所示顺序测试 ):

    • 输入序列中出现文件结束条件(在这种情况下执行 setstate(eofbit))
    • 下一个可用字符 c 是分隔符,由 Traits::eq(c, delim) 确定。 分隔符被提取(与 basic_istream::get() 不同)并计入 gcount(),但不存储。
    • count-1 个字符已被提取(在这种情况下会执行 setstate(failbit))。

    这意味着,当用户输入的字符超过N 时,找不到分隔符,并且N+1-1 字符已被提取。

    【讨论】:

      【解决方案2】:

      根据documentation,第二个参数N + 1必须包含'\0'空终止符。因此,abcd 输入不是有效输入,因为getline() 需要5 的大小来存储字符串以及'\0'

      【讨论】:

      • 我认为你落后了。 N+1 必须包含空字符,但这会自动附加到数组中。所以getline(arr, N+1) 只提取第一个N 字符,因此仍有空间存储'\0'。在这种情况下,如果输入是abcd,它只提取abc,然后附加空字符。但是在通过 while 循环的下一个循环中,getline 不会暂停输入。
      猜你喜欢
      • 2013-04-23
      • 1970-01-01
      • 1970-01-01
      • 2017-04-07
      • 1970-01-01
      • 1970-01-01
      • 2014-09-25
      • 2011-06-18
      • 1970-01-01
      相关资源
      最近更新 更多