2016-11-07 96 views
3

爲了澄清,我並不過分擔心數據丟失,因爲這是用於記錄我的應用程序中的操作,我使用wstring作爲主數據類型。由於我目前使用的框架的性質(OpenFrameworks日誌記錄默認爲std::string,我很好)。將std :: wstring轉換爲cstring是否安全?

這裏是我的電流轉換的例子:

//ofLog.h--patch | `message` is a `std::ostringstream` 
    ofLog& operator<<(const std::wstring& value){ 
     message << value.c_str() << padding; 
     return *this; 
    } 

通過使用這種特定的過載,我可以節省自己很多煩惱的詳細日誌和不用太擔心,如果我有第三方的std ::字符串(OSC(char)庫vs JSON(wchar)庫)。

我對C++相對來說比較陌生,曾經生活在Java/JavaScript世界,我只是想知道在這裏有沒有其他潛在的數據丟失風險。這個問題是否有平臺無關的解決方案?我一直在谷歌搜索幾個小時,我想有一個「安全」的解決方案,不會咬我的道路。

基本上我的解決方案似乎可行,但我想知道這樣做是否有潛在的問題。

謝謝! (在了openFrameworks標籤只是爲了幫助人們在路上,如果我們解決它)

編輯 如果有人需要這個的了openFrameworks以下似乎爲我工作:

/* 
ofLog.h 
*/ 
     /// \brief Overload the wstring operator so that this actually works for 
     /// data of that format 
     /// 
     ofLog& operator<<(const std::wstring& value){ 
      std::string cvalue; 
      std::transform(value.begin(), value.end(), 
       std::back_insert_iterator<std::string>(cvalue), 
       [](wchar_t wide) 
       { 
        return static_cast<char>(wide > 127 ? '?' : wide); 
       }); 

      message << cvalue << padding; 
      return *this; 
     } 

     /// \brief Overloaded to support wchar_t * types 
     /// 
     /// 
     ofLog& operator<<(const wchar_t* value) 
     { 
      std::wstring wstr(value); 
      std::string cvalue; 
      std::transform(wstr.begin(), wstr.end(), 
       std::back_insert_iterator<std::string>(cvalue), 
       [](wchar_t wide) 
      { 
       return static_cast<char>(wide > 127 ? '?' : wide); 
      }); 

      message << cvalue << padding; 
      return *this; 
     } 
//END ofLog.h 
+0

你期望你的'wstring'主要由US-ASCII內容組成嗎? –

+0

是的,我懷疑它幾乎總是ASCII爲關鍵信息 –

+0

爲std :: wstring :: c_str(),它返回常量wchar_t *;但是,std :: ostringstream沒有運算符<<重載取const const wchar_t *作爲論點;它可能選擇operator <<(void *),這可能不是你想要的。 –

回答

3

的顯示的代碼不會正常工作。 std::wstringc_str()方法返回const wchar_t *。將它傳遞到std::ostringstreamoperator<<將選擇operator<<超載,該參數需要const void *參數,該參數不會完成任何有用的操作。

您聲明您期望您的std::wstring主要由US-ASCII字符組成。如果是這樣,hackiest方法是粗暴的std::wstring轉換爲std::string,通過以下方式,用問號代替所有非ASCII字符(或挑選自己喜歡的標點符號):

std::string cvalue; 

std::transform(value.begin(), value.end(), 
       std::back_insert_iterator<std::string>(cvalue), 
       [](wchar_t wchar) 
       { 
        return static_cast<char>(wchar > 127 ? '?':wchar); 
       }); 

繼續,並<<普通std::string納入您的message

如果你希望你的寬字符串主要由US-ASCII內容組成,那麼這將是一件很快完成的工作。否則,需要使用本地化庫來使用當前系統區域設置將寬字符串正確轉換爲窄字符串。相當多的工作...

+0

謝謝Sam,有沒有可能在boost庫或另一個公共庫中挖掘轉換作爲參考點?與此同時,這個項目的「黑客」似乎很好。 –

+0

如果你的實現使用unicode來處理它的寬字符,並且你的locale字符集是非常合理的'UTF-8',那麼我只需要插入[我自己的Unicode庫](http://www.courier-mta .ORG /統一字符編碼/ unicode__iconvert__fromu.html)。 –

+0

我想轉換爲UTF-8會比扔高價值更好 –