开发者

c++ getline cin issue

 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);
    }
  }

in this example, if I get a socket error I'm kindly asking the user if he wants to exit the program by getting an input. And then comparing that input by some other value in this case its a "yes" string. But for some reason even if I type "yes" it skips the if check. and prints the "Connection with the server is lo开发者_开发知识库st. Do you want to exit?" again. The strange thing is, if I type "yes" again it works. I tried to fix it by using cin.ignore(); and all those stuff, but no solution.


Well, you don't seem to have any way of exiting the loop if you enter yes, it simply prints test and continues on its merry way, trying to read more data.

If you mean that it's not printing test the first time you enter yes then you need to temporarily change:

getline(cin,input);

to:

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

to try and find out what's actually in that buffer when you come to compare it.


For what it's worth, this code (very similar to yours) works just fine:

#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;
}

You should also be aware that you have a gaping hole in your logic. When you do a strtok on your buffer, it modifies the buffer and gives you a pointer into it (i.e., the actual buffer). It doesn't make a copy for you.

If you then save away those pointers in info and pass this off to another thread, at the same time as you go back and read more information into that buffer then your main thread, and the thread you passed the information to, are going to clash. Badly.

If you must use strtok to get the information, make sure you strdup it and pass the copies to your other thread (remembering to free them when done). Most C implementations will have a strdup (though it's not ISO standard). If yours doesn't, see here.

There's a moderately good chance this hole may be causing your strange behaviour.

The best way to fix this is to change the two lines:

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

into:

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

and remember to free both those memory allocations in your other thread when it's finished with them (normally I wouldn't advocate malloc-type operations for C++ but, since you're already using character buffers rather than strings, it seems the easiest solution).


Perhaps try:

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

Because it sounds like you might have a \n sitting in the cin buffer (perhaps from a previous cin operation). That code above should flush cin ready for getline().


How can it print the message again? I see no while loop here. Is the code snippet you posted within a loop?


When people post code - wondering why it doesn't work - I always look for the checks they've put in for failure, based on the documented API of the functions they're calling. I rarely find them. Nor any effort to trace the values in variables. Same here.

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

Please consider changing this to:

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";

Then, tell us what you see....

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜