将字节序列转换为ASCII表示,反之亦然

时间:2011-08-30 13:15:19

标签: c++ string stl

假设我们有一个uint8_t的向量:{ 0x12 0x34 0xab 0xcd }。我发现我可以使用ostringstream将其转换为字符串"1234abcd"(没有空格,没有0x前缀)。但我不能简单地用istringstream将其转换回来,显然因为它没有空格。 hex + setw(2)操纵者没有帮助。有没有简单的方法将这些字符串转换为相应的字节序列(除了编写我自己的解析器,至少)?无法在ASCII字符串中引入空格和其他分隔符。

3 个答案:

答案 0 :(得分:1)

你可以通过一个循环中的一对字符来提供你的istringstream。我确定 ) 使用.str()

答案 1 :(得分:1)

不是最好的方式,我相信,但仍然:

void BytesToString(unsigned char* bt, char* str)
{
 int len = sizeof(bt);

 for (int i = 0; i < len; i++)
 {
  sprintf(str + i*2, "%2.2x", bt[i]);
 }
}

void StringToBytes(char* str, unsigned char* bt)
{
 unsigned int sz = strlen(str);
 if ((sz % 2) == 1)
 {
  //was too lazy to prepend 0 to the string or write a separate case for that one, whatever

  puts("Bad input #1");
 }

 memset(bt, 0, sz/2);

 unsigned char temp = 0;
 for (unsigned int step = 0; step < sz; step++)
 {
  if (str[step] >= 0x30 && str[step] <= 0x39) {temp = (unsigned char)str[step] - 0x30;}
  else
   if (str[step] >= 0x61 && str[step] <= 0x7A) {temp = (unsigned char)str[step] - 0x57;}
        else {/* Is not an ASCII HEX string (illegal character) */   puts("Bad input #2");}

  bt[(step - step % 2) / 2] += temp*(0x01 + 0x0F*(!(step % 2)));
 }
}

答案 2 :(得分:1)

您可以创建一个代理对象,从istringstream

中精确读取两个字符
struct U8 {
  unsigned int datum;
  friend std::istream& operator>>(std::istream&is, U8& u) {
    char s[3] = "xx";
    if(!((is>>s[0]) && (is>>s[1]) && (std::istringstream(s) >> std::hex >> u.datum)))
      is.setstate(std::ios::badbit);
    return is;
  }
  operator unsigned int() const { return datum; }
};

你会这样使用它:

U8 nextByte;
iss >> nextByte;
std::cout << nextByte;
uint8_t ch = nextByte;

完整的程序如下:

#include <sstream>
#include <iomanip>
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <cassert>

typedef std::vector<unsigned char> V;

std::string Stringify(const V& v) {

  std::ostringstream oss;

  oss << std::hex;
  for(V::const_iterator it = v.begin(); it != v.end(); ++it) {
    oss << std::hex << (unsigned int)*it;
  }
  return oss.str();
}


struct U8 {
  unsigned int datum;
  friend std::istream& operator>>(std::istream&is, U8& u) {
    char s[3] = "xx";
    if(!((is>>s[0]) && (is>>s[1]) && (std::istringstream(s) >> std::hex >> u.datum)))
      is.setstate(std::ios::badbit);
    return is;
  }
  operator unsigned int() const { return datum; }
};

const V UnStringify(const std::string& str) {
  V v;
  std::istringstream iss(str);

  std::copy(std::istream_iterator<U8>(iss),
            std::istream_iterator<U8>(),
            std::back_inserter(v));

  return v;
}


int main() {
  V v;
  v.push_back(0x12);
  v.push_back(0x34);
  v.push_back(0xab);
  v.push_back(0xcd);

  std::cout << Stringify(v) << "\n";
  assert(v == UnStringify("1234abcd"));
}