2013-06-13 62 views
3

我在basic_ostream對象的write方法讀了,這就是我對cppreference發現:關於性病:: basic_ostream ::寫

basic_ostream& write(const char_type* s, std::streamsize count); 

表現爲UnformattedOutputFunction。構造並檢查哨兵對象後,輸出字符數組中第一個元素由s指向的連續位置中的字符。

  • 恰好count字符插入
  • 插入輸出序列失敗(在此情況下setstate(badbit)稱)

:直到以下情況之一時字符被插入到輸出序列所以我得到它將一個緩衝區中的字符塊寫入流中。字符數是由count指定的字節數。但是有一些我不確定的事情。這是我的問題:

  • 我應該使用write只有當我想指定我想多少字節寫入流?因爲通常當您打印一個char數組時,它將打印整個數組,直到達到空字節,但是當您使用write時,您可以指定要寫入多少個字符。

    char greeting[] = "Hello World"; 
    
    std::cout << greeting;  // prints the entire string 
    std::cout.write(greeting, 5); // prints "Hello" 
    

    但也許我誤解了這個東西。

  • 而且我經常會看到這樣使用write代碼示例:

    stream.write(reinterpret_cast<char*>(buffer), sizeof(buffer)); 
    

    爲什麼reinterpret_castchar*被使用?我應該何時知道在寫入流時做類似的事情?

如果任何人都可以幫助我解決這兩個問題,將不勝感激。

回答

2

•我是否應該僅在要指定要寫入流的字節數時使用寫入?

是 - 你應該使用write當有您希望我們寫入流,才能在內存中連續排列的數據字節的具體數量。但是有時你可能需要特定數量的字節,需要以另一種方式獲取它們,例如通過格式化double的ASCII表示以具有特定的寬度和精度。其他時間你可以使用>>,但是它必須是非內置類型的用戶定義的,當它被定義時 - 通常更好,但它可能會更糟 - 你的目的 - 它會打印任何類設計器選擇的,包括潛在的數據,這些數據是通過指針或引用以及感興趣的靜態數據和/或動態計算的值從對象鏈接的。它可能會改變數據表示形式:例如將二進制double s轉換爲ASCII表示,或者確保網絡字節順序,而不管主機的字節順序如何。它也可以省略某些對象的數據,如緩存項,用於管理計數器但不填充等方面的數據,數組元素沒有邏輯部分..

爲什麼是燒焦了的reinterpret_cast *正在使用?我應該何時知道在寫入流時做類似的事情?

write()函數簽名期望const char*參數,所以這個轉換正在完成。只要您無法獲得char*的數據,您就需要使用演員表。

演員陣容反映出write()將對象第一個字節處開始的數據視爲8位值,而不考慮數據的實際預製類型。這與能夠執行諸如float的最後一個字節的write()和出現在相同結構中的下一個double的前3個字節之類的事情 - 在reinterpret_cast<>之後所有的數據邊界和解釋都會丟失。 (當你從輸入流中執行read()字節時,你實際上應該更加小心......假如你讀取的數據構成double,當寫入內存時,這些數據沒有正確對齊double,然後嘗試使用它作爲double,你可能會得到一個SIGBUS或類似的對齊異常從您的CPU或性能下降取決於您的系統。)

1

basic_ostream::write及其對應部分basic_istream::read用於在數據流上執行未格式化的I/O。通常,這是原始的二進制數據,可能包含或不包含可打印的ascii字符。

read/write和其他格式的運營商如<<>>getline等之間的主要區別在於,前者不會使對數據的任何假設正在對工作 - 你必須在什麼字節得到完全控制讀取並寫入流。與可能跳過空格的後者相比,丟棄或忽略它們等。

要回答第二個問題,reinterpret_cast <char *>用於滿足函數簽名並且一次處理一個字節的緩衝區。不要讓類型char欺騙你。使用char的原因是因爲它是語言提供的最小的內置原語類型。也許一個更好的名字可能類似uint8,表明它確實是一個無符號的字節類型。

+0

因此,通過您的解釋,理論上你可以傳遞一個'bool *'到'reinterpret_cast'因爲它也是一個字節? – 0x499602D2

+0

@ 0x499602D2好點。這將是一種類型不匹配。 – greatwolf

+0

@ 0x499602D2:它不會是一個類型不匹配......「布爾*」就像任何其他指針一樣......它有一些字節數(對於32位應用程序通常是4,對於64位通常是8 ),你可以'reintrepret_cast'到'c​​har *'並開始從存儲'bool'的地址寫入字節。在C++ 03中,「bool」的大小是未指定的,但C++ 11引入了默認和程序員控制......對它們沒有特別的瞭解,特別是「bool *」不是某種指向(如果可能的話)轉換成char *'怪異/有損)。 –