2014-01-22 84 views
6

我在使用c套接字的C++編寫程序。我需要一個函數來接收我想返回一個字符串的數據。我知道這是行不通的:C++從套接字讀取到std :: string

std::string Communication::recv(int bytes) { 
    std::string output; 
    if (read(this->sock, output, bytes)<0) { 
     std::cerr << "Failed to read data from socket.\n"; 
    } 
    return output; 
} 

因爲read() *函數需要一個字符數組指針參數。這裏返回一個字符串的最好方法是什麼?我知道我理論上可以將數據讀入char數組,然後將其轉換爲字符串,但這對我來說似乎很浪費。有沒有更好的辦法?

*我其實並不在乎自己使用的是其他的東西read()如果有一個更合適的替代

這裏是所有的代碼上引擎收錄,應在一週內到期。如果我不通過則有一個答案,我會重新發布它:http://pastebin.com/HkTDzmSt

[更新]

我使用&output[0]也嘗試過,但得到的輸出包含以下內容:

jello! 
[insert a billion bell characters here] 

「jello!」是將數據發送回套接字。

+1

c_str()是const,你不能這樣做。只需讀入一個緩衝區,然後複製到一個字符串。 – billz

+0

@billz正確,我收回我的建議。 – Borgleader

+0

這是甚至適當的形式?如果不是,我應該採取什麼不同的做法? – 735Tesla

回答

4

這裏有一些功能,應該可以幫助你實現你想要的。它假定你只會從套接字的另一端收到ASCII字符。

std::string Communication::recv(int bytes) { 
    std::string output(bytes, 0); 
    if (read(this->sock, &output[0], bytes-1)<0) { 
     std::cerr << "Failed to read data from socket.\n"; 
    } 
    return output; 
} 

std::string Communication::recv(int bytes) { 
    std::string output; 
    output.resize(bytes); 

    int bytes_received = read(this->sock, &output[0], bytes-1); 
    if (bytes_received<0) { 
     std::cerr << "Failed to read data from socket.\n"; 
     return ""; 
    } 

    output[bytes_received] = 0; 
    return output; 
} 

當打印弦,一定要使用cout << output.c_str()日期:STRING overwrite operator<<,直到它達到size skip不可打印的字符。最終,您也可以在功能的最後調整大小,以便能夠使用正常的cout

正如在註釋中指出的那樣,首先發送大小也是避免字符串類可能不必要的內存分配的好主意。

+0

我仍然得到了我在上次評論中鏈接的相同輸出。有趣的是,看起來鈴鐺的字符大約等於「jello!」的長度。從1024(我目前使用的字節數爲參數)減去 – 735Tesla

+0

如果這有幫助,我將所有的代碼發佈到pastebin上:http://pastebin.com/HkTDzmSt – 735Tesla

+1

@ 735Tesla您應該首先發送字符串的長度。然後,在接收時,首先閱讀該長度,以瞭解接下來要閱讀的內容。通過使用固定的長度進行接收,您將等待什麼和/或將垃圾讀入字符串。 –