7

vector<char>aをaにstd::string変換し、一方通行で変換したいと思います。

私はもうすぐそこにいますが、以下のコードの結果は、vector<string>1つの文字列(ベクトル内のすべての文字列部分の連結)が必要な場合です。

詳細については、私のコード例を参照してください。

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

演算子=が次のように定義されている文字列タイプ用に独自のback_insert_iteratorを作成します(stl libのコードを見てください。かなり簡単です)。

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

ラムダを使用して結果文字列の関数を呼び出しましたが、ラムダが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 に答える