1
 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

4 回答 4

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对缓冲区执行 a 时,它会修改缓冲区并为您提供指向它的指针(即实际缓冲区)。它不会为您制作副本。

如果您随后保存这些指针info并将其传递给另一个线程,同时您返回并将更多信息读入该缓冲区,那么您的主线程和您将信息传递给的线程将会发生冲突。很糟糕。

如果您必须使用strtok来获取信息,请确保您使用strdup它并将副本传递给您的其他线程(记住在完成后释放它们)。大多数 C 实现都会有一个strdup(尽管它不是 ISO 标准)。如果您没有,请参阅此处

这个洞很有可能会导致你的奇怪行为。

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

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

进入:

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

并记住free在其他线程中完成这些内存分配(通常我不会提倡mallocC++ 的 -type 操作,但是,由于您已经在使用字符缓冲区而不是字符串,这似乎是最简单的解决方案)。

于 2011-07-07T05:00:27.197 回答
2

也许尝试:

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

因为听起来您可能在 cin 缓冲区中有一个 \n (可能来自先前的 cin 操作)。上面的代码应该为 getline() 刷新 cin。

于 2011-07-07T04:50:51.403 回答
0

它如何再次打印消息?我在这里看不到 while 循环。您发布的代码片段是否在循环中?

于 2011-07-07T04:51:20.640 回答
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";

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

于 2011-07-07T06:07:30.340 回答