【问题标题】:void* of a bool[] conversion to std::string [closed]void* 的 bool[] 转换为 std::string [关闭]
【发布时间】:2013-01-24 12:55:01
【问题描述】:

我需要保存一些数据,唯一可行的选择是std::string;所以我得到一个作为void* 传递的布尔数组。现在我需要以一种可以将其转换为std::string 并能够从该确切字符串中读取void*bool[] 的方式保存它。可悲的是,我迷失在转换中。

f(const void* data, int length){

   bool** boolPointer = (bool**)(data);
   bool boolArray[length];

   for (int i=0; i<=length; i++){
       boolArray[i] = p[sizeof(bool)*i];
   }

   std::string s = (std::string&)boolArray;
}

我很确定最后一行没有可行的转换,但那是我的尝试。

【问题讨论】:

  • 为什么需要将其转换为 std::string? std::string 应该有什么样的格式?不能简单地将某些东西转换为字符串。
  • 你应该使用for (int i=0; i&lt;length; i++) &lt; 而不是&lt;=
  • @Ashot 如果有的话,他应该做std::copy(boolPointer, boolPointer+length, &amp;boolArray[0])。但我根本不明白为什么需要这样做。
  • @R.遗憾的是,Martinho Fernandes 在项目中已经很晚了,std::string 是数据保存机制的接口。
  • 重要的部分是字符串应该具有的格式。您不只是“转换为字符串”。你“建立一个特定格式的字符串”。

标签: c++ type-conversion void-pointers


【解决方案1】:

这对你有用吗?

char f(bool b)
{
    return b ? '1' : '0';
}

int main()
{
    // let's just consider whatever is there in this uninitialized array
    bool buf[100];

    std::string s;

    // transform and copy (convert true to '1' and false to '0')
    std::transform(&buf[0], &buf[99], std::back_inserter(s), f);

    std::cout << s << std::endl;
}

如果你是C++11,可以使用下面的代码sn-p

int main()
{
    bool buf[100];

    std::string s;

    std::transform(&buf[0], &buf[99], std::back_inserter(s), [](bool const &b){ return b ? '1' : '0'; });
    std::cout << s << std::endl;
}

【讨论】:

  • [](bool b) { return b ? '1' : '0'; } ?
  • @Bartek Banachewicz:最初写了这个并删除了,因为我没有注意到 C++11 标签:)。
  • @Bartek Banachewicz:好的,谢谢。如果这是指导方针,我会得到纠正。
  • 为什么不使用 &buf[100] ? ..一个通过结束??
【解决方案2】:

您可以重载输出运算符以将布尔值转换为您想要的任何值:

ostream& operator<<(const ostream& os, const bool& value) {
    return os << (value ? "1" : "0");
}

然后将数组复制到stringstream

int main() {
    // ...
    ostringstream oss;
    copy(data, data+size, ostream_iterator<bool>(oss));

    oss.str(); // this is the string you're looking for
    // ...
}

【讨论】:

    【解决方案3】:

    好吧,我想你可以打开你的 C++ 书...

    std::string f(std::vector<unsigned char> const& v)
    {
        std::string temp;
    
        for (auto c : v) {
            for (unsigned i = 0; i < 8; ++i) {
                temp += (c & (1 << i)) ? '1' : '0';
            }
        }
    
        return temp;
    }
    

    使用std::copy 或其他一些神秘的back_inserter 之类的东西可能更容易做到这一点,但我想保持简单。另一种选择是使用std::bitset 或您自己的封装,以摆脱丑陋的位操作。

    如果你被魔鬼逼着通过void*传递数据,只需将其转换为向量即可:

    unsigned char* begin = static_cast<unsigned char*>(data);
    vector<unsigned char> v (begin, begin + length);
    

    还请注意,如果它是用于序列化目的,那么计算机和人类都很难读取该表示。如果它打算由计算机读取,请将其保存为二进制而不进行转换。如果它是供人类阅读的,请将其保存为十六进制字符(将每个字节分成两半)。

    【讨论】:

    • 我不确定他是否使用 C++11。至少没有这样标记
    • @Chubsdad 我使用的是 current 标准,恰好是 C++11。如果他需要使用 older 标准,他应该适当地标记它。
    • 如果我没看错的话,c++11 是用于与新 C++ 标准有关的问题的标签
    • @Chubsdad 这会使大量问题被不当标记。无论如何,将示例转换为 C++03 相当容易。
    • @Chubsdad 不,C++ 标签用于 C++,C++XX 标签用于特定于 XX 版本 C++ 的问题。就这么简单
    猜你喜欢
    • 2011-03-05
    • 1970-01-01
    • 2020-03-28
    • 2016-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多