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

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 lost. 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.

akk kur
  • 361
  • 2
  • 5
  • 14

4 Answers4

4

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).

Community
  • 1
  • 1
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • yes exactly. it's not printing "test" the first time I enter "yes". it also skips the cout statement you posted. – akk kur Jul 07 '11 at 05:04
  • whatever I try it always skips the next line after getline the first time. – akk kur Jul 07 '11 at 05:06
  • This is really weird. it's exactly the same code as I have, but for some reason mine is not working. – akk kur Jul 07 '11 at 05:13
  • Remember stdout is buffered. So just writing "test" to cout does not neccessarily mean thats when it will be written to the terminal. Either flush stdout after your print, or use stderr (`cerr`) instead as it is usually unbuffered. – Sodved Jul 07 '11 at 05:35
  • @Sodved, yes, cout is buffered. However, OP stated that `connection lost` was being printed _again_ with no intervening `test`. No amount of buffering would cause that :-) – paxdiablo Jul 07 '11 at 05:40
2

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().

fileoffset
  • 956
  • 6
  • 9
  • I tried every possible coombination of cin.ignore, cin.clear, fflush still not working. – akk kur Jul 07 '11 at 05:05
  • i dont think it could be because of a buffer...if it was it would not prompt him for an input..it would straight extract away any delimiting character...and the loop would run again with cin stream cleared... – jemmanuel Jul 07 '11 at 05:41
0

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

Sharath
  • 1,627
  • 2
  • 18
  • 34
  • Ok, now it is clear. You are not exiting the loop even if the answer is "yes". Use break or exit(0) if the answer is yes. – Sharath Jul 07 '11 at 05:07
  • No its not the problem. the problem is whatever I try it always skips the next line after getline the first time. So even if I type if(input == "yes") break; it skips the break; – akk kur Jul 07 '11 at 05:11
0

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....

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252