C ++白线跳过错误

时间:2016-09-30 08:33:46

标签: c++

此代码是"游戏的一部分"我在Win32中开发:

    cout << "You find another deep red apple. Eat or drop?\n";
        cin>>noskipws>>sa;
        while (sa != "Eat"&&sa != "Drop"&&sa != "eat"&&sa != "drop")
        {
            cout << "That's not a valid answer. Please choose from the options you were given." << endl;
            cin >> sa;
        }

然后它进入一个说"That's not a valid answer. Please choose from the options you were given."

的循环

如何使代码工作,以便它读取带有空格的字符串而不会发生这种情况?我也试过getline(),但它没有用。

3 个答案:

答案 0 :(得分:2)

您不想完全清楚自己想做什么以及想要接受什么样的输入。现在我猜你想在一次调用中读取包含空格的字符串。为此,最简单的方法是使用std::getline()。你说你试过了它并没有起作用,你究竟是怎么尝试的以及什么都没有用?

回到你的代码,我会尝试解释为什么它按照它的方式工作,但我不会为你重写它,你必须尝试修复靠你自己。

基本上问题是std::noskipws并没有以你期望的方式帮助你。它确实在流上设置了一个标志,使其在读取时不会跳过空格字符。所以你可以做这样的事情,例如:

char c1, c2, c3;
std::cin >> std::noskipws >> c1 >> c2 >> c3;

如果你运行它并输入&#34; a b c&#34;在输入提示符上,三个char的值将是&#39; a&#39;,&#39; &#39; (空格)和&#39; b&#39;。

如果您改为运行:

char c1, c2, c3;
std::cin >> c1 >> c2 >> c3;

值将是&#39; a&#39;&#39; b&#39;和&#39; c&#39;。

但是,您不是直接阅读单个字符,而是在阅读std::string。当您执行此操作std::cin >> someString时,无论您是否设置了该标志,读取将停在第一个空格字符处。所以如果你有这个:

std::cin >> std::noskipws >> sa;

然后你输入让我们在提示符上说这个:&#34;不吃不吃&#34;。上面的调用仍然会将第一个单词&#34; not&#34;,只读到saif将失败,您将打印该消息,然后尝试再次从流中读取。

现在有趣的部分开始了。此时流内容如下所示:&#34;吃或掉#34;开头有一个空格,因为您已经设置了该标志,所以不会被忽略和跳过。但是现在对operator>>()的字符串调用因为开头的那个空格而失败了。这会在流上设置fail位并且不会读取任何内容。从此刻开始,流仍然处于失败状态,从现在开始每次调用std::cin >> sa都会立即无声地失败并且您有一个无限循环来继续打印该消息。

有关operator>>std::string的工作原理的详细信息,请参阅this link

稍后修改

如果你使用std::getline()时看起来第一个调用没有等待输入并且只是立即返回一个空字符串,则有一个解释。在调用getline()之前的某个地方检查是否有任何&#34;正常&#34;来自cin的输入(使用operator>>)。让我们在getline()之前说你做这样的事情(不一定在同一个函数中):

SomeType var;
std::cin >> var;

当这要求输入时,您可能在终端上输入类似的内容:value<ENTER>。这会读取值,但很可能会在流中留下新行字符。因此,在此之后第一次调用getline()时,它将读取并丢弃新行字符并返回(可能是空字符串)。 解决此问题的一种方法是在调用getline()之前对流进行一些清理,例如:

cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

这基本上忽略了之前输入的所有剩余字符,并允许您从干净的流开始。

答案 1 :(得分:0)

如果要修剪输入字符串,可以使用提升字符串算法,请参阅示例here

#include <iostream>
#include <boost/algorithm/string.hpp>

int main() {
    string sa;
    while (std::getline(cin, sa)) {
        boost::trim(sa);       // remove leading & trailing whitespace
        if (sa == "Eat" || sa == "Drop" || sa == "eat" || sa == "drop") {
            std::cout << "Option was " << sa << std::endl;
            break;
        } 
        std::cout << "That's not a valid answer." << std::endl;
    }
    return 0;
}

输入(行开头的一些空格):

   WrongInput
     Eat

输出:

That's not a valid answer. Please choose from the options you were given.
Option was Eat

答案 2 :(得分:0)

涉及一些编码,用do-while循环替换你的while循环,并使用字符串查找功能来搜索你的单词。 接下来有一段代码可以解决你的问题,尝试一下,如果它对你有益,你可以给它评分。

mongoexport --host a.a.a.a --port 2346234 -slaveOk 1 -d meritnation -c user_rewards_points --csv --out badgesnew.csv -f userId, TotalPoints, Bronze.DEDICATED, Bronze.STUDIOUS, Bronze.FUN_LEARNER, Bronze.POPULAR, Bronze.ENLIGHTENED, Bronze.ENTHUSIAST, Bronze.WELL_CONNECTED, Bronze.AUTOBIOGRAPHER