C ++输入未正确阻止

时间:2015-05-27 07:54:58

标签: c++ multithreading c++11 input console-application

我正在写语音沟通者。我必须从控制台控制程序,因为我们决定不开发GUI - 它并不重要,而且需要时间。因此,有一个线程可以从控制台处理用户命令:

void* ClientApp::commandHandler(void)
{
    std::string input;
    std::string connPort;
    std::string connAddr;
    std::map<std::string, int> mapStringValues;
    mapStringValues["connect to server"] = 1;
    mapStringValues["connect to host"] = 2;
    mapStringValues["disconnect from server"] = 3;
    mapStringValues["start call"] = 4;
    mapStringValues["end call"] = 5;
    mapStringValues["set TCP port"] = 6;
    mapStringValues["help"] = 7;
    mapStringValues["exit"] = 8;

    std::cout << "Write command" << std::endl;
    //int i = 0;

    while(true)
    {
        //std::cout<< ++i<<std::endl;
        std::getline(std::cin, input);

        switch(mapStringValues[input])
        {
            case 1:  //connect to server
                std::cout << "TODO: connect to server" << std::endl;
                break;

            case 2:  //connect to host
                std::cout << "IP:" << std::endl;
                std::getline(std::cin, connAddr);
                std::cout << "port:" << std::endl;
                std::getline(std::cin, connPort);
                connectToHost(connAddr, std::stoi(connPort));
                break;

            case 3:  //disconnect from server
                std::cout << "TODO: disconnect from server" << std::endl;
                break;

            case 4:  //call
                if(callInProgres == true)
                {
                    break;
                }
                networkController->udpConnect();
                startCallViaNet();
                break;

            case 5:  //end call
                endCallViaNet();
                break;
            case 6: 
                break;
            case 7:
                showCommands();
                break;
            case 8:
                audioPlayer->stopThread();
                audioRecorder->stopThread();
                networkController->stopSendUDPThread();
                networkController->stopRecvUDPThread();
                networkController->stopRecvTCPThread();
                networkController->shutdownUdpConnection();
                networkController->shutdownTcpConnection();
                exit(0);
                break;
        }
    }
}

当我必须接听来电时出现问题。我需要输入,所以我可以写是或否。处理互联网连接的线程调用要求并得到答案的函数(y / n)。下一步操作取决于acceptCall函数返回的内容。我知道这会导致麻烦 - 许多线程要求输入。所以为了防止它,在线程调用此函数之前,它终止了commandHandler线程(它是pthread并且我取消它 - 可能不优雅,但工作正常),获取输入然后再次启动commandHandler:

int ClientApp::acceptCall(std::string ip)
{
    std::cout << "Start call from "<<ip<<"? (y/n)" << std::endl;
    char c = (char)getchar();  /* std::cin, getline, scanf... - I tied it*/
    if(c == 'y'){
        return 0;
    }
    else{
        return -1;
    }
}

然后当我拒绝呼叫并且它再次启动commandHandler时发生了一些奇怪的事情。来自commandHandler的第一个getline不再需要输入。循环开始工作,无法输入。我正在尝试所有可能的输入函数std :: cin.ignore()和std :: cin.clear()的所有组合。我成功的最好的是在另一个commandHandler启动后阻塞getline,但我的命令与switch中的任何情况都不匹配 - 命令是正确的,但没有,除了输入后发生一个循环周期。我生气了。我阅读了数百个关于C ++输入的线程,但没有任何帮助我。

1 个答案:

答案 0 :(得分:0)

让我猜一下,当您使用getchar获得输入时,您使用换行符结束输入?然后getchar读取并提取从缓冲区输入的字符,但保留换行的下一个输入操作的新行。

如果有输入应该被忽略,那么标准的C ++方法是调用流函数调用std::istream::ignore。请点击链接,它会显示如何使用它的示例。