【问题标题】:C++ putting a 2d array of floats into a char*C++ 将一个二维浮点数组放入 char*
【发布时间】:2010-06-07 20:56:09
【问题描述】:

我正在尝试将浮点数(输入)的二维向量放入 c++ 中的 char*(输出)中。

void foo(const std::vector<std::vector<float> > &input, char* &output )
{  
   char charBuf[sizeof(output)];
   int counter = 0;
   for(unsigned int i=0; i<input.size(); i++)
   {
      for(unsigned int p=0; p<input.at(i).size(); p++)
      {
         //what the heck goes here
      }
   }

【问题讨论】:

  • 您应该将迭代器传递给您的函数,而不是传递向量上的引用。
  • @Alerty——为什么?这是我不知道的某种风格吗?通过引用传递不会进行复制,并且您会知道您获得的任何迭代器都将位于向量的开头。
  • @mmr:您可以使用迭代器来简化代码。这是一个例子:stackoverflow.com/questions/2991753/…
  • @Alerty-- 不过,您还是希望有人使用有效的迭代器调用该函数,即从开头开始而不是从开头+随机开始的迭代器。在这里,您必须为内部循环传递一个迭代器数组,所以我不确定这是否节省了这么多。
  • @Alerty - 抱歉,如果这变得有点刻薄 - 这不是我的意图。您向我展示了我知识中的一些非常大的漏洞,感谢您指出。随着我对这些事情的了解越来越多,我对可能应该重构的代码量感到更加畏惧......

标签: c++ serialization type-conversion


【解决方案1】:

您可以在每次迭代中使用std::stringstream 将浮点数放入std::string,然后从中获取char* 数组。如果你想要一个大的char* 数组,那么只需使用在循环之外定义的单个字符串流。

【讨论】:

    【解决方案2】:

    这很大程度上取决于您所说的“将它们放入 char*”的意思。

    【讨论】:

    • -1 因为这不是答案。 +1的问题非常需要澄清。所以,我的最终行动是这条评论。
    【解决方案3】:

    如果您希望结果是人类可读的,那么您就在snprintf() 之后——这会将数字 3.1415 转换为字符串“3.1415”。如果您只是输出数据以供另一个程序重新读取,那么您可以将二进制数据转储到您的输出流中。

    请记住,当您输出浮点数的二进制表示时,您必须了解它的编码方式。如果你在同一个平台上读写,那么编码将是相同的。事实上,大多数桌面平台使用 IEEE-754 规范来处理浮点数,但为了安全起见,请检查一下。

    此外,请确保您的输出流允许某种版本控制或其他机制,以便稍后在您决定对其执行不同操作时修改格式。通常只在开头加上一个版本号就足够了。

    【讨论】:

    • 看来您可能需要澄清“只是将二进制数据转储到输出流中”是什么意思——至少,我不确定这是什么意思,因为他不(然而)有一个输出流,只是一个 char*。
    • snprintf() 已经过时了 ;)
    • @mmr: 是的,这篇文章原本比较长,但后来我决定详细解释如何走这条路弊大于利,因为它需要更多的研究你可以理解你真正在做什么。
    【解决方案4】:

    您尝试执行的操作称为序列化。 C++ 常见问题解答有专门的部分:http://www.parashift.com/c++-faq-lite/serialization.html

    【讨论】:

      【解决方案5】:

      以下代码将为您提供char* 参数中所有floats 的input 视图。

      但是,我会非常小心,这实际上是您想要的。 char* 数组不是 endian 健壮的,我总是尽量避免将分配的指针交给用户。任何使用此函数的人都需要将outputdelete[] 解除分配,但这从函数名称或签名中看不出来,这是脆弱代码的秘诀。

      void foo(const std::vector<std::vector<float> > &input, char* &output )
      {  
         //this was likely an error, it is always an array of size 4
         //char charBuf[sizeof(output)];
      
         std::vector<float> tmp_output;
      
         int counter = 0;  // Why was this here?
      
         for(unsigned int i=0; i<input.size(); i++)
         {
            // This is slightly more efficient than the hand rolled loop below.
            // std::copy( input[i].begin(), input[i].end(),
            //            std::back_inserter<float>(tmp_output) );
      
            for(unsigned int p=0; p<input.at(i).size(); p++)
            {
               tmp_output.push_back(input.at(i).at(p));
            }
         }
         output = new char[tmp_output.size()*sizeof(float)];
         std::copy( reinterpret_cast<const char*>(&(*tmp_output.begin())),
                    reinterpret_cast<const char*>(&(*tmp_output.end())),
                    output );
      }
      

      【讨论】:

        【解决方案6】:

        不要尝试将数据放入原始字符数组中,尤其是当您不知道它们的大小时 - 您在这里不知道。改用std::stringstd::stringstream 来写信给它。

        无论你做什么,摆脱那个charBuf的东西;你用它做的任何事情都是错误的,因为sizeof(output) 不是输出数组的大小。

        假设您想要一个人类可读的字符串,您可能想要类似

        std::string foo(const std::vector<std::vector<float> > &input)
        {
            std::ostringstream stream;
            for (std::size_t i = 0; i < input.size(); ++i)
            {
                if (i != 0) stream << "\n";
                for (std::size_t j = 0; j < input[i].size(); ++j)
                {
                    if (j != 0) stream << ",";
                    stream << input[i][j];
                }
            }
        
            return stream.str();
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-07-17
          • 2023-04-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多