C++将包含非人类可读数据的字符串转换为 200 双精度



我有一个长度为 1600 的字符串,我知道它包含 200double。当我打印出字符串时,我得到以下内容:Y���Vz'@��y'@��!U�}'@�-...

我想将此字符串转换为包含 200 个双精度的向量。

这是我尝试的代码(blobString是一个 1600 个字符长的字符串(:

string first_eight = blobString.substr(0, sizeof(double)); // I get the first 8 values of the string which should represent the first double
double double_value1
memcpy(&double_value1, &first_eight, sizeof(double)); // First thing I tried
double* double_value2 = (double*)first_eight.c_str();  // Second thing I tried
cout << double_value1 << endl;
cout << double_value2 << endl;

这将输出以下内容:

6.95285e-310
0x7ffd9b93e320

---编辑解决方案---

第二种方法有效,我所要做的就是看看double_value1指向的地方。

cout << *double_value2 << endl;

下面是一个示例,可能会让您更接近所需的内容。请记住,除非 Blob 中的数字采用特定 C++ 编译器预期的确切格式,否则这不会像预期的那样工作。在我的例子中,我自己正在建立双精度的缓冲区。

让我们从我们的双打阵列开始。

double doubles[] = { 0.1, 5.0, 0.7, 8.6 };

现在,我将构建一个应类似于 blob 的std::string。请注意,我不能简单地使用指向双精度列表基础的(char *)初始化字符串,因为它将在命中第一个零字节时停止!

std::string double_buf_str;
double_buf_str.append((char *)doubles, 4 * sizeof(double));
// A quick sanity check, should be 32
std::cout << "Length of double_buf_str " 
<< double_buf_str.length()
<< std::endl;

现在,我将c_str()指针重新解释为(double *),并遍历四个双精度。

for (auto i = 0; i < 4; i++) {
std::cout << ((double*)double_buf_str.c_str())[i] << std::endl;
}

根据你的具体情况,可以考虑对 Blob 使用std::vector<uint8_t>,而不是std::string。C++11 为您提供了一个data()函数,相当于此处的c_str()。将你的 blob 直接变成双精度向量会给你一些更容易使用的东西 - 但要到达那里,你可能不得不弄脏一个resize,然后直接memcpy到内部数组中。

我给你举一个完整性的例子。请注意,这当然不是您通常初始化双精度向量的方式......我想象我的double_blob只是一个指向一个 blob 的指针,其中包含正确格式的已知数量的双精度

const int count = 200; // 200 doubles incoming
std::vector<double> double_vec;
double_vec.resize(count); 
memcpy(double_vec.data(), double_blob, sizeof(double) * count);
for (double& d : double_vec) {
std::cout << d << std::endl;
}

@Mooning Duck 提出了一个重要的观点,即c_str()的结果不一定与适当的边界对齐——这是不使用std::string作为通用 blob 的另一个很好的理由(或者至少不要解释内部结构,直到它们被复制到某个地方,以保证你感兴趣的类型的有效对齐(。尝试从内存中的非对齐位置读取双精度值的影响因体系结构而异,这给您带来了可移植性问题。在基于 x86 的机器中,AFAIK 只会对性能产生影响,因为它将跨对齐边界读取并正确组装双精度值(您可以在 x86 机器上对此进行测试,方法是写入然后从缓冲区中的连续位置读回双精度,偏移量增加 1 字节 - 它会工作(。在其他架构中,你会得到一个错误。

std::vector<double>解决方案不会受到此问题的影响,因为可以保证标准中内置的新内存的对齐。

最新更新