给定 std::hex、uint8_t 与 int 的 strringstream 中的不同行为

问题描述

我认为 uint8_t 实际上只是 char 的别名这一事实意味着当 stringstream 中的字符被读回时,它们被本地存储,即字符的 ascii 代码,而如果 char 被输入到int,指定了 std::hex,它被读入为转换为基数 10 的十六进制数字。

这是一个展示行为的小例子,但我问的原因是因为我一开始假设指定 unit8_t 的输出向量是正确的方法,因为我稍后需要将此向量作为数组提供到一个 C 函数作为一个字节向量(你将它作为一个空指针传入,它会以某种方式弄清楚如何处理它)。所以我认为将输入字符对读入字符串流,然后读入 uint8_t 将帮助我跳过手动位移。有没有办法保持读入 uint8_t 的想法但唤起对 int 的处理?我可以在从 stringstream 读取时转换为 int 吗?或者什么?

#include <iostream>
#include <string>
#include <sstream>
#include <iostream>
#include <iomanip>

#include <vector>
#include <cstdint>

int main (int argc,char** argv) {
  uint8_t n = 0;
  std::stringstream ss;
  ss << 'F';
  ss >> std::hex >> n;
  std::cout << "uint8:" << (int)n << std::endl;

  int m = 0;
  std::stringstream tt;
  tt << 'F';
  tt >> std::hex >> m;
  std::cout << "int:" <<  std::hex << m << std::endl;
  
  return 0;
}

输出

uint8:70
int:f

解决方法

charsigned charunsigned charoperator>> 重载,它们都从流中读取单个字符。 uint8_t 参数选择 unsigned char 重载作为最佳匹配,读取 F 作为字符(ASCII 代码 70 或 0x46)。

要匹配整数提取 operator>> 重载,请使用类型为 short 或更大的参数(例如 uint16_t):

  uint16_t n = 0;
  std::stringstream ss;
  ss << 'F';
  ss >> std::hex >> n;

我可以在从字符串流读取时转换为 int 吗?

没有。参数是通过引用获取的,它在函数调用中用作指针。将 uint8_t 参数设置为 (int&) 的类型将调用未定义的行为。只需使用更大的类型即可。