c ++ getline cin问题

时间:2011-07-07 04:36:23

标签: c++ getline cin

 while (true)
 {
    int read = recvData(clientSocket, buf, sizeof(buf));
    if(read == SOCKET_ERROR)
    {
        cout<<"Connection with the server is lost. Do you want to exit?" << endl;
        string input;
        getline(cin,input);
        if(input == "yes")
            cout<<"test";
    }
    if(read == SHOW )
    {
        char *p = strtok(buf, " ");
        while (p) 
        {
            cout<<p<<endl;
            p = strtok(NULL, " ");
        }
    }

    else if(read == SEND )
    {
        UDPinfo* info = new UDPinfo;
        char *p = strtok(buf, " ");
        info->_IP = p;
        p = strtok(NULL, " ");
        info->_Port= p;
        info->_filePath = filePath;
        info->_UPDsock = UDPSocket;
        //Starting UDP send thread.
        _beginthread(UDPsendThread, 0, (void*)info);
    }
  }

在这个例子中,如果我收到套接字错误,我很乐意询问用户是否要通过获取输入来退出程序。然后在这种情况下将该输入与其他值进行比较,其为“是”字符串。但由于某种原因,即使我输入“是”,它也会跳过if检查。并打印“与服务器的连接丢失。你要退出吗?”再次。奇怪的是,如果我再次输入“是”,它就会起作用。我尝试使用cin.ignore()修复它;以及所有这些,但没有解决方案。

4 个答案:

答案 0 :(得分:4)

好吧,如果你输入yes,你似乎没有办法退出循环,它只是打印test并继续它的快乐方式,尝试读取更多数据。

如果您的意思是在您第一次输入test时没有打印yes,那么您需要暂时更改:

getline(cin,input);

为:

getline (cin, input);
cout << "[" << input << "]" << endl;

尝试在比较它时找出 缓冲区中的实际内容。


对于它的价值,这段代码(与你的代码非常相似)工作正常:

#include <iostream>

int main (void) {
    while (true) {
        int read = -1;
        if (read == -1) {
            std::cout << "Connection lost, exit?" << std::endl;
            std::string input;
            getline (std::cin, input);
            std::cout << "[" << input << "]" << std::endl;
            if (input == "yes") {
                std::cout << "You entered 'yes'" << std::endl;
                break;
            }
        }
        std::cout << "Rest of loop" << std::endl;
    }
    return 0;
}

你还应该意识到你的逻辑上有一个漏洞。当您在缓冲区上执行strtok时,它会修改缓冲区并为您提供指向它的指针(即实际缓冲区)。它不会为你制作副本。

如果你然后在info中保存那些指针并将其传递给另一个线程,同时返回并将更多信息读入该缓冲区然后你的主线程,以及传递信息的线程,将发生冲突。不好。

如果您必须使用strtok来获取相关信息,请确保strdup并将副本传递给其他主题(完成后请记住将其释放)。大多数C实现将具有strdup(尽管它不是ISO标准)。如果您没有,请参阅here

这个洞可能会引起你的奇怪行为。

解决此问题的最佳方法是更改​​两行:

    info->_IP = p;
    info->_Port= p;

成:

    info->_IP = strdup (p);
    info->_Port= strdup (p);

并记住free在你的另一个线程中完成它们时的那些内存分配(通常我不会提倡malloc - 为C ++键入操作但是,因为你已经在使用了字符缓冲而不是字符串,似乎是最简单的解决方案。)

答案 1 :(得分:2)

也许试试:

cin.clear(); 
cin.ignore(INT_MAX,'\n');

因为听起来你可能有一个\ n坐在cin缓冲区(可能来自之前的cin操作)。上面的代码应该为getline()冲洗cin。

答案 2 :(得分:0)

如何再次打印邮件?我在这里看不到while循环。您在循环中发布的代码段是什么?

答案 3 :(得分:0)

当人们发布代码时 - 想知道为什么它不起作用 - 我总是根据他们调用的函数的文档化API来查找他们为失败而进行的检查。我很少找到它们。也没有任何追踪变量值的努力。同样在这里。

string input;
getline(cin,input);
if (input == "yes")
    cout<<"test";

请考虑将此更改为:

string input;
if (getline(std::cin, input))
    std::cerr << "input [" << input.size() << "] '" << input << "'\n";
else
    std::cerr << "getline() was unable to read a string from std::cin\n";

然后,告诉我们你看到了什么......