簡體   English   中英

轉換矢量 <char> 到具有轉換的字符串

[英]Convert a vector<char> to a string with a conversion

我想將vector<char>轉換為std::string並進行轉換。

我差不多了,但是下面代碼的結果是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實現呢?

你快到 ; 這工作:

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

但不幸的是,這會實例化很多字符串流,效率很低。 理想情況下, ConvertHexToAscii (錯誤命名,順便說一下!C ++不知道編碼)函數會直接使用底層流。

#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;
}

創建自己的back_insert_iterator(查看stl lib中的代碼,這很簡單)對於字符串類型,其中operator =定義為

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;
  }
};

您可以使用函數輸出迭代器執行此操作:

#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選擇正確的重載。

雖然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();

但是任何事情都可能比創建一大堆臨時字符串更好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM