将 std::string 转换为无符号字符数组
Posted
技术标签:
【中文标题】将 std::string 转换为无符号字符数组【英文标题】:convert std::string to unsigned char array 【发布时间】:2018-08-15 07:27:24 【问题描述】:我正在使用 c++/cli 进行编码,我正在尝试将文本框中的字符串分配给 unsigned char 数组。我已经完成了从 String^ 到 std::string 的转换。
我知道这是可能的
unsigned char test[] = "abcde";
但是,我试图将字符串变量传递到数组中。下面的字符串变量用于演示目的。同时,我不知道数组的恒定长度值
string str = "abcde";
unsigned char test[] = str.c_str();
我要求类型为unsigned char [6]
希望有人能找到解决方法。谢谢
unsigned char [6]
【问题讨论】:
How to convert a string literal to unsigned char array in visual c++的可能重复 你为什么想要/需要这个?请在您的问题中注入一些上下文。我几乎可以肯定,您真的需要复制数据。 【参考方案1】:标准方式:
#include <vector>
#include <string>
std::vector<unsigned char> to_vector(std::string const& str)
// don't forget the trailing 0...
return std::vector<unsigned char>(str.data(), str.data() + str.length() + 1);
int main()
std::string str = "abcde";
auto v = to_vector(str);
一种使用可变长度数组扩展的方式,在某些编译器上可用:
#include <vector>
#include <string>
std::vector<unsigned char> to_vector(std::string const& str)
// don't forget the trailing 0...
return std::vector<unsigned char>(str.data(), str.data() + str.length() + 1);
int main()
std::string str = "abcde";
unsigned char v[str.length() + 1];
std::copy(str.data(), str.data() + str.length() + 1, v);
但请注意:
main.cpp:14:37: warning: ISO C++ forbids variable length array 'v' [-Wvla]
unsigned char v[str.length() + 1];
^
... 这是另一种确保我们使用对数组的引用的方法。请注意,该引用仅在当前线程中有效,并且仅在下一次调用to_array()
之前有效。但请注意,这都是不必要的。
#include <vector>
#include <string>
#include <iostream>
unsigned char (& to_array(std::string const& str))[]
static thread_local std::vector<unsigned char> result;
result.assign(str.data(), str.data() + str.length() + 1);
return reinterpret_cast<unsigned char (&)[]>(*result.data());
extern "C" void foo(unsigned char p[])
int main()
std::string str = "abcde";
unsigned char (&v)[] = to_array(str);
foo(v); // ok
foo(reinterpret_cast<unsigned char*>(str.data())); // also ok!
【讨论】:
感谢您的帮助,但我需要v
为 unsigned char[ ]
类型
@spn161 为什么你认为它需要是那种类型的?
我正在调用一个库中的函数,该函数要求该变量属于该类型
@spn161 这并不意味着您需要创建一个新数组。你几乎可以肯定地给它一个指向std::string
的缓冲区(char*
)的指针,安全地转换为unsigned char*
(尽管要仔细阅读这个库函数的作用并确保它与施加在你身上的约束兼容std::string
)。您是否探索过这个选项?
@spn161 添加了另一个选项。但是......真的我认为你需要检查库是否真的需要对数组的引用。【参考方案2】:
您实际上想要做的是找到“abcde”的地址并将其作为指针传递给 unsigned char*。然后你就可以毫无问题地以数组的形式访问它。
幸运的是,如果您查看 str.c_str(),您会发现它已经返回了一个指针(abcde 的地址)。 所以你所要做的就是把它保存到一个变量中。 此处示例:
string str = "abcde";
unsigned char* test = (unsigned char*)str.c_str();
您可以毫无问题地将其作为数组使用。
for (int i = 0; i < str.size(); i++)
cout << test[i];
如果要复制字符串,可以使用以下方法进行
unsigned char* test = (unsigned char*)malloc(str.size());
memcpy(test, str.c_str(), str.size());
我们所做的是分配内存空间,我们可以在其中使用 malloc 复制字符串的内容。 然后我们使用 memcpy 从 str.c_str() 返回的地址(其中包含“abcde”)复制到内容,并将其复制到我们在使用 malloc 之前创建的新分配空间的地址。
【讨论】:
你可能更愿意复制字符串,因为c_str()
返回的指针可能会在稍后调用str
的方法时失效。
这取决于程序员。如果您在范围内使用变量,则不应使其无效。如果你在范围之外使用它们,你可以使用 memcpy 来解决这个问题。
c_str
返回一个const
限定的指针。从 C++17 开始,data
返回一个非const
限定的指针,这里感觉更合适。而且这里没有理由使用malloc
,是吗?在这种情况下,与 new
相比,它没有任何优势,并且至少有一个明显的劣势:malloc
使得将结果与标准库的智能指针类型一起使用变得更加困难。
在这种非常特殊的情况下,new 和 malloc 之间没有区别。 new/delete 调用构造函数/析构函数; new 是类型安全的, malloc 不是; new 可以被一个类覆盖。我们在这里使用的不是类,而是原语。并且类型安全问题在这里非常小(通常您必须将 malloc 返回的 void* 转换为正确的指针类型以将其分配给类型化的指针变量,这可能很烦人,但远非“不安全”)。而且为了简单起见,我使用了 c_str(),因为结果是一样的,而且问的问题更少。
如果我们要在您的第一个解决方案之后放置一个断点,它会在 Autos 选项卡下的 Type 标题下返回一个 unsigned char *
。我需要一个unsigned char [6]
,而不是使用unsigned char test[] = "abcde";
行显示,我需要在函数中调用test 变量。非常感谢以上是关于将 std::string 转换为无符号字符数组的主要内容,如果未能解决你的问题,请参考以下文章