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

时间:2017-08-03 23:14:56

标签: c++

我有一个长度为1600的字符串,我知道它包含200 double。当我打印出字符串时,我得到以下内容: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;

1 个答案:

答案 0 :(得分:1)

这是一个可以让您更接近您需要的例子。请记住,除非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直接转换为 double 的向量将为您提供更容易使用的东西 - 但是为了实现这一目标,您可能必须弄脏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的另一个好理由(或至少不要解释内部,直到它们被复制到某个地方,保证你感兴趣的类型有效对齐)。尝试从内存中的非对齐位置读取double的影响因架构而异,这给您带来了便携性问题。在基于x86的机器中,只有性能影响AFAIK,因为它将跨对齐边界读取并正确组装双精度(您可以通过写入然后从后续读取双精度来在x86机器上测试它)缓冲区中具有增加的1字节偏移量的位置 - 它只是工作)。在其他架构中,您会遇到错误。

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