2012-04-11 71 views
4

是否有可能使用std :: string作爲read()?是否有可能使用一個std ::字符串read()?

例子:

std::string data; 

read(fd, data, 42); 

Normaly,我們必須使用的char *,但它可以直接使用的std :: string? (我寧願不創建店面的結果爲char *)如果讀取功能需要一個char *,則沒有

感謝的

+0

如果零拷貝是你的目標,它是否會幫助你用「mmap」替換「read」,然後在它周圍包裝一個固定分配的std :: string? – user1202136 2012-04-11 13:11:50

+0

您正在閱讀的字符串中是否有空格? – 2012-04-11 14:07:36

回答

7

嗯,你需要創建一個char*莫名其妙,因爲這就是 函數所需要的。 (順便說一句:你所談論的POSIX函數 read,不是你,而不是std::istream::read?)這個問題不是 的char*,這是什麼char*點(我懷疑是什麼 你實際上意味着)。

最簡單和常用的解決方案在這裏將使用本地陣列:如果您想直接捕捉到std::string

char buffer[43]; 
int len = read(fd, buffer, 42); 
if (len < 0) { 
    // read error... 
} else if (len == 0) { 
    // eof... 
} else { 
    std::string data(buffer, len); 
} 

,然而,這是 可能(雖然不一定是個好主意):

std::string data; 
data.resize(42); 
int len = read(fd, &data[0], data.size()); 
// error handling as above... 
data.resize(len); // If no error... 

這樣避免了複製,但坦率地說......相比於時間的副本是微不足道 必要的實際讀取和 分配Ø f字符串中的內存。這也有(產生的 可以忽略)缺點,結果字符串具有42字節的實際緩衝區 (四捨五入到任何值),而不僅僅是實際讀取字符所需的最小值 。

(而且因爲人們有時會提出這個問題,關於該 連續性內存在std:;string:這是一個問題,十個或更多 年前std::string原來的規格設計 expressedly允許非連續的。實施中,沿着 當時流行的rope類的行。實際上,沒有一個實現者發現這個 是有用的,人們確實開始假設連續性。在這一點上,標準委員會決定將該標準與現行的 慣例對齊,並要求連續性。所以......沒有實現從來沒有過 連續的,沒有前途的實施將放棄連續性, 鑑於C++ 11的要求。)

+0

「這可以避免複製,但很坦率地說...複製與實際讀取和分配所需時間相比是微不足道的在字符串中的內存「。這取決於正在讀取的數據的大小。人們投入了大量精力,使Linux內核在多個數據傳輸路徑上零拷貝。 – user1202136 2012-04-11 13:08:14

+0

@ user1202136在這種情況下,副本的大小爲42個字節。並且有一個動態分配,並從系統傳輸字節。內核中的情況不同,至少在處理諸如緩衝區(可能大約4KB或更多,並且從池中分配)等事情時。 – 2012-04-11 13:45:54

0

。只要首先調整大小,就可以使用char的std :: vector的第一個元素的地址。我不認爲舊的(C++ 11之前的)字符串是保證連續的內存,否則你可以做一些類似的字符串。

0

不,你不能,你不應該。通常,std :: string實現內部存儲其他信息,例如分配內存的大小和實際字符串的長度。 C++文檔明確指出修改由c_str()data()返回的值會導致未定義的行爲。

0

沒有,但

std::string data; 
cin >> data; 

的作品就好了。如果你真的想要read(2)的行爲,那麼你需要分配和管理你自己的字符緩衝區。

+0

這將打破空白。 – 2012-04-11 12:25:52

+2

我們可以從這個問題中得知所有可能的結果...... – DRVic 2012-04-11 12:29:12

0

因爲read()方法適用於原始數據輸入,標準::字符串實際上是一個不好的選擇,因爲std :: string處理文本。 std :: vector似乎是處理原始數據的正確選擇。

-1

使用字符串庫中的std :: getline - 請參閱cplusplus.com - 可以從流中讀取並直接寫入字符串對象。例如(從cplusplus.com再次撕開 - 第一次打在谷歌函數getline):

int main() { 
    string str; 
    cout << "Please enter full name: "; 
    getline (cin,str); 
    cout << "Thank you, " << str << ".\n"; 
} 

從標準輸入(CIN),並從文件(ifstream的)閱讀時那麼會工作。

+0

爲什麼這是相關的?讀取是在posix上的系統調用,並且與控制檯無關。 – 2016-10-12 14:04:55

相關問題