std :: cin和std:.getline

时间:2019-11-19 11:37:44

标签: c++ windows visual-studio command-line

你好[对不起我的英语不好]

我用C ++用Winsock编写了一个小型网卡游戏(控制台应用程序)。基本上,程序执行以下方式:

1) Open Socket and wait for a peer to connect
2) If connected -> start game
3) If its your turn -> decide which action should be taken next and type it in
3.1) If its not your turn -> wait for your peers decision

当用户在等待时,他们可以在控制台中键入一些内容(实际上在键入时不会打印出来)。如果用户轮到他,可能会有三种结果:

1) The user inputs only valid data -> program runs fine
2) The user inputs trash while waiting but doesnt press enter (no \n)
3) The user inputs trash while waiting and does press enter (\n)

在情况2)和3)中,我有一个大问题:由于输入缓冲区中似乎还剩下一些输入,因此我对std :: getline的调用(以获取用户输入)占用了用户输入的垃圾以前。

示例: 我启动程序并等待其他用户加入我的游戏。 等待期间,我在控制台中输入“ abc”,然后按Enter。 另一个用户加入了游戏。 在完成一些设置工作之后,程序应该接受我的输入,以便我可以决定下一步要执行的操作。但这不会发生。首先,“ abc”被打印在屏幕上,其次,该程序不等待我的输入,因为它使用“ abc”作为std :: getline调用的输入。

下面是一个代码示例,用于重现我的“问题”:

int main()
{
    std::string str;
    std::cout << "Before sleep";
    std::this_thread::sleep_for(5s);

    std::cin.ignore(std::numeric_limits<std::streamsize>::max());
    std::cin.clear();

   std::getline(std::cin, str);
}

我使用this_thread :: sleep_for(5s)模拟了“等待”。在等待期间,您可以输入垃圾,并根据您的输入在5秒后将其打印出来,并等待更多输入,或者如果您不使用std :: cin.ignore和std :: cin.clear则结束程序。

std :: ignore()和std :: clear似乎不按照我认为的工作方式工作(清除输入缓冲区并重置std :: cin状态标志)

我的问题:

1)如何在获得用户输入之前清空输入缓冲区?

2)为什么控制台会打印我的输入?

1 个答案:

答案 0 :(得分:0)

在“ cin”语句后使用“ std :: cin.ignore(std :: numeric_limits :: max(),'\ n');”;丢弃输入流中的所有内容,包括换行符。

这是我的代码:

int main()
{
    std::string str;
    std::cout << "Before sleep\n";

    ……//Simulate wait time

    std::string str1;
    std::cin >> str1;
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');  
    std::getline(std::cin, str);
    std::cout << str;
}

我在等待时间内输入“ ASD”,并在等待时间过后打印“ ASD”。然后我继续输入字符,只输出稍后输入的字符。

编辑:如果要实现在等待时间内输入的废纸does不会出现在控制台上?如果是这样,我建议您可以尝试运行代码:

#include <iostream>
#include <chrono>
#include <thread>
#include<string>
#include <limits>
#include<stdio.h>
#include<windows.h>
#include <WinBase.h>

using namespace std::chrono_literals;

int main()
{
    std::string str;
    std::cout << "Before sleep\n";
    std::this_thread::sleep_for(5s);
    std::getline(std::cin, str);



    int i;
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    GetConsoleScreenBufferInfo(hConsole, &csbi);
    COORD pos = { 0,1 };
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
    for (i = 1; i <= 10; i++)
        std::cout << ' ';
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);


    std::cin.get();
    std::cin.clear();  // Reset all state values in the stream to valid values
    std::cin.sync();   //Empty stream

    std::getline(std::cin, str);
}