【问题标题】:How to Convert unsigned char* to std::string in C++?如何在 C++ 中将 unsigned char* 转换为 std::string?
【发布时间】:2009-11-04 12:20:29
【问题描述】:

我有unsigned char*,想把它转换成std::string。你能告诉我最安全的方法吗?

【问题讨论】:

  • C++ 没有字节类型,所以你需要告诉我们实际上是什么类型。
  • BYTE 解析为“无符号字符”
  • 那么Byte 呢?更重要的是,你的指针指向什么?单个Byte 值还是Byte 数组?你想在你的字符串中做什么:指针或字符串值的文本表示,它表示指向的对象的值?

标签: c++ bytearray byte


【解决方案1】:

您只需要将unsigned char 转换为char,因为string 类没有接受unsigned char 的构造函数:

unsigned char* uc;
std::string s( reinterpret_cast< char const* >(uc) ) ;

但是,如果您的字节数组包含空值,您将需要在构造函数中使用长度参数,就像您不这样做一样,只有部分数组将在字符串中结束(数组直到第一个空值)

size_t len;
unsigned char* uc;
std::string s( reinterpret_cast<char const*>(uc), len ) ;

【讨论】:

  • BYTE * pbData = "SomeString" size_t length = 10 我有手头的长度,所以我使用了这个:我使用了这个方法,“std::string(reinterpret_cast(pbData) , 长度 );”它有效,但有一次我看到 memcpy 崩溃。试图找出我们为什么会发生崩溃,尽管它似乎对我有用
  • 作为一个可移植的书呆子,我想指出这仅适用于具有 2 的补码算法的系统。在 1 的补码或符号幅度架构上,在 char*unsigned char* 之间进行 reinterpret_cast 是不安全的(嗯,这是安全的,但如果 char 被签名并且任何字符都有顶部,你会得到令人惊讶的结果位设置)。在这种情况下,提问者显然是在 Windows 上,所以没问题。
【解决方案2】:

BYTE* 可能是unsigned char* 的 typedef,但我不能肯定。如果您告诉我们BYTE 是什么,将会有所帮助。

如果 BYTE* 是 unsigned char*,您可以使用 std::string 范围构造函数将其转换为 std::string,该构造函数将采用两个通用迭代器。

const BYTE* str1 = reinterpret_cast<const BYTE*> ("Hello World");
int len = strlen(reinterpret_cast<const char*>(str1));
std::string str2(str1, str1 + len);

话虽如此,您确定这是个好主意吗?如果 BYTEunsigned char 它可能包含非 ASCII 字符,其中可能包含 NULL。这将使strlen 给出不正确的长度。

【讨论】:

    【解决方案3】:
    BYTE *str1 = "Hello World";
    std::string str2((char *)str1);  /* construct on the stack */
    

    或者:

    std::string *str3 = new std::string((char *)str1); /* construct on the heap */
    cout << &str3;
    delete str3;
    

    【讨论】:

    • 它不起作用,我收到一条错误消息“'std::basic_string<_elem>::basic_string(const std::allocator<_ty> &)' : cannot convert parameter 1 从 'BYTE *' 到 'const std::allocator<_ty> &'"
    • 这是因为std::string 没有采用unsigned char* 的构造函数,因此编译器依赖于用于分配器的模板化构造函数。您需要使用 std::string(Iterator begin, Iterator end)std::string(const char*, std::size_t n) 并将 BYTE* 转换为 char*
    • std::string &amp;str3 = new ...,你不是说* 而不是&amp;吗?顺便说一句,在堆上创建 std::string 通常是个坏主意,并且破坏了具有值语义的字符串类的一半目的。
    • 你没事。我没有像我应该的那样通过编译器运行它。您将需要 (char *) 类型转换,因为 std::string 不处理 BYTE/unsigned char 类型。并且参考示例是错误的;它应该是一个指针。
    • 这个答案有很多问题:C 风格的强制转换,无缘无故使用堆分配等等。
    【解决方案4】:

    BYTE 只不过是typedef unsigned char BYTE;

    您可以轻松使用以下任何构造函数

    string ( const char * s, size_t n );
    string ( const char * s );
    

    【讨论】:

      【解决方案5】:

      这是完整的代码

      #include <bits/stdc++.h>
      
      using namespace std;
      
      typedef unsigned char BYTE;
      
      int main() {
        //method 1;
        std::vector<BYTE> data = {'H','E','L','L','O','1','2','3'};
        //string constructor accepts only const char
        std::string s((const char*)&(data[0]), data.size());
        std::cout << s << std::endl;
      
        //method 2
        std::string s2(data.begin(),data.end());
        std::cout << s2 << std::endl;
      
        //method 3
        std::string s3(reinterpret_cast<char const*>(&data[0]), data.size()) ;
        std::cout << s3 << std::endl;
       
        return 0;
      }
      

      【讨论】:

        【解决方案6】:

        如果可以访问 CryptoPP

        无符号字符的可读十六进制字符串

        std::string& hexed = "C23412341324AB";
        uint8_t      buffer[64] = {0};
        StringSource ssk(hexed, true,
                    new HexDecoder(new ArraySink(buffer,sizeof(buffer))));
        

        回来

        std::string hexed;
        uint8_t val[32]  = {0};
        StringSource ss(val, sizeof(val), true,new HexEncoder(new StringSink(hexed));
        // val == buffer
        

        【讨论】:

          猜你喜欢
          • 2013-07-18
          • 2011-07-23
          • 2012-11-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-10-11
          相关资源
          最近更新 更多