将std :: wstring转换为cstring是否安全?

时间:2016-11-07 02:24:37

标签: c++ openframeworks

为了澄清,我并不过分担心数据丢失 ,因为这是针对我的应用程序中的日志记录操作而我使用wstring作为主要数据类型。由于我目前正在使用的框架的性质(OpenFrameworks日志记录默认为std::string,我很好)。

以下是我目前转换的一个示例:

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

通过使用这个特定的重载,我可以在Verbose日志中省去很多烦恼,如果我有第三方std :: strings(例如OSC(char)库和JSON(wchar)库),不要太担心。

我对于生活在Java / JavaScript世界中的C ++相对较新,我只是想知道除了潜在的数据丢失之外还有什么风险。这个问题是否有与平台无关的解决方案?我一直在谷歌搜索几个小时,我希望有一个“安全”的解决方案,不会让我在路上咬我。

基本上我的解决方案似乎有效,但我想通过这样做来了解是否存在潜在的问题。

谢谢! (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

1 个答案:

答案 0 :(得分:3)

显示的代码无法正常工作。 std::wstring&#39; c_str()方法返回const wchar_t *。将其传递给std::ostringstream operator<<会选择operator<<重载,该const void *重载会带来std::wstring参数,而这些参数无法完成任何有用的操作。

您声明您希望std::wstring主要由US-ASCII字符组成。如果是这样,最苛刻的方法是以下列方式粗略地将std::string转换为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); }); ,用问号替换所有非ASCII字符(或选择您最喜欢的标点符号):

<<

继续,std::string普通message进入with open('example.txt', 'r') as f: cur_key = None value_list = [] for line in f.readlines(): key, value = line.split() value = value.strip() if not cur_key: cur_key = key if cur_key == key: value_list.append(value) else: print(cur_key + ":" + ', '.join(value_list)) cur_key = key value_list = [value] print(cur_key + ":" +', '.join(value_list))

如果您希望您的宽字符串主要由US-ASCII内容组成,那么这将很快完成工作。否则,需要使用本地化库来使用当前系统区域设置将宽字符串正确转换为窄字符串。相当多的工作......