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

また、ロジックに大きな穴があることにも注意する必要があります。バッファに対してa を実行するstrtokと、バッファが変更され、そこへのポインタ (つまり、実際のバッファ) が与えられます。コピーは作成されません。

次に、これらのポインターを保存infoして別のスレッドに渡すと、戻ってそのバッファーにさらに情報を読み込むと同時に、メインスレッドと情報を渡したスレッドが衝突します。ひどく。

strtok情報を取得するために使用する必要がある場合は、それを確認してコピーを他のスレッドにstrdup渡します (完了したら解放することを忘れないでください)。ほとんどの C 実装には(ISO 標準ではありませんが) があります。そうでない場合は、こちらを参照してください。strdup

この穴があなたの奇妙な行動を引き起こしている可能性は中程度です。

これを修正する最善の方法は、次の 2 行を変更することです。

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

の中へ:

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

freeそして、それらが終了したら、他のスレッドでこれらの両方のメモリ割り当てを覚えておいてください (通常、私はmallocC++ の型操作を推奨しませんが、文字列ではなく文字バッファーを既に使用しているため、最も簡単な解決策のようです)。

于 2011-07-07T05:00:27.197 に答える
2

おそらく試してみてください:

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

\n が cin バッファーにあるように聞こえるためです (おそらく以前の cin 操作から)。上記のコードは、getline() の準備ができている cin をフラッシュする必要があります。

于 2011-07-07T04:50:51.403 に答える
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 に答える
0

どうすればメッセージを再度印刷できますか? ここにはwhileループがありません。投稿したコード スニペットはループ内ですか?

于 2011-07-07T04:51:20.640 に答える