7

我想将 a 转换vector<char>为 astd::string并以一种方式进行转换。

我快到了,但是下面代码的结果是 a vector<string>,而我想要一个字符串(向量中所有字符串部分的串联)。

有关详细信息,请参阅我的代码示例。

string ConvertHexToAscii(const char input)
{
    std::ostringstream oss;
    oss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(input);
    return oss.str();
}

vector<char> readBuffer; // this is my input

readBuffer.push_back(0x1c);
readBuffer.push_back(0x09);

vector<string> resultVec;

std::transform(readBuffer.begin(), readBuffer.end()
    , back_inserter(resultVec)
    , ConvertHexToAscii);

// resultVec[0] = "1C";
// resultVec[1] = "09";

我需要的结果是一个包含“1C09”的字符串。如何做到这一点std::transform

4

5 回答 5

5

你快到;这有效:

std::stringstream sstr;
std::transform(
    input.begin(), input.end(),
    std::ostream_iterator<std::string>(sstr, ""),
    ConvertHexToAscii);

但不幸的是,这实例化了相当多的字符串流,效率低下。理想情况下,ConvertHexToAscii(顺便说一句,C++ 不知道编码)函数将直接使用底层流。

于 2012-06-28T09:46:40.810 回答
3
#include <iostream>
#include <vector>
#include <iomanip>
#include <sstream>
#include <numeric>

std::string ConvertHexToAscii(std::string acc, char input)
{
  std::ostringstream oss;
  oss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(input);
  return acc + oss.str();
}


int main() {
  std::vector<char> readBuffer; // this is my input
  readBuffer.push_back(0x1c);
  readBuffer.push_back(0x09);

  std::cout << std::accumulate(readBuffer.begin(), readBuffer.end()
          , std::string(), ConvertHexToAscii) << std::endl;

  return 0;
}
于 2012-06-28T10:17:30.990 回答
1

为 operator = 定义为的字符串类型创建自己的 back_insert_iterator

template< class string_type, class value_type >
class back_insert_iterator
{
public:
  back_insert_iterator< _string_type >& operator = ( const value_type& val )
  {
    container->append( val )
    return *this;
  }
};
于 2012-06-28T09:48:49.443 回答
1

您可以使用函数输出迭代器执行此操作:

#include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <iterator>
#include <iomanip>
#include <boost/function_output_iterator.hpp>

std::string ConvertHexToAscii(const char input)
{
    std::ostringstream oss;
    oss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(input);
    return oss.str();
}

int main() {
    std::vector<char> readBuffer; // this is my input

    readBuffer.push_back(0x1c);
    readBuffer.push_back(0x09);

    std::string temp;

    std::transform(readBuffer.begin(), readBuffer.end()
    , boost::make_function_output_iterator([&temp](const std::string& r) {temp.append(r);})
    , ConvertHexToAscii);


    std::cout << temp << std::endl;
}

我使用 lambda 来调用append()结果字符串上的函数,但如果你没有可用的函数,它相当容易使用boost::bind,或者只需编写一个老式的仿函数来为你做这件事。

使用boost::bind函数输出迭代器创建为:

boost::make_function_output_iterator(boost::bind(static_cast<std::string& (std::string::*)(const std::string&)>(&std::string::append), &temp, _1))

反而。它有点笨重,因为您需要为std::string::append.

于 2012-06-28T09:51:34.757 回答
0

虽然 perreal 使用累积的想法并没有那么糟糕,但直接在流上操作而不是创建这么多临时字符串可能会更高效(尽管移动语义可能对此有所帮助):

std::ostringstream os;
std::string temp = std::accumulate(
                       readBuffer.begin(), readBuffer.end(), std::ref(os), 
                       [](std::ostream &os, const char input) 
                       -> std::reference_wrapper<std::ostream> {
                           return os << std::hex << std::setw(2) 
                                     << std::setfill('0') 
                                     << static_cast<int>(input);
                       }).str();

编辑:但是好吧,这可能有点过于复杂了,一个简单的 foreach 也可以完成(即使不像积累那样语义干净):

std::ostringstream os;
std::for_each(readBuffer.begin(), readBuffer.end(), 
              [&os](const char input) mutable {
                  os << std::hex << std::setw(2) << std::setfill('0') 
                     << static_cast<int>(input);
              });
std::string temp = os.str();

但任何事情都可能比创建一大堆临时字符串更好。

于 2012-06-28T10:51:20.547 回答