2016-11-07 95 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会比扔高价值更好 –