C++ 从std::stringstream中读取uint8_t作为数字类型
我的理解是,从C++ 从std::stringstream中读取uint8_t作为数字类型,c++,C++,我的理解是,从stringstream读取uint8\u t是一个问题,因为stringstream将uint8\u t解释为char。我想知道如何将uint8\t作为数字类型从stringstream中读取。例如,以下代码: #include <iostream> #include <sstream> using namespace std; int main() { uint8_t ui; std::stringstream ss("46");
stringstream
读取uint8\u t
是一个问题,因为stringstream
将uint8\u t
解释为char
。我想知道如何将uint8\t
作为数字类型从stringstream
中读取。例如,以下代码:
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
uint8_t ui;
std::stringstream ss("46");
ss >> ui;
cout << unsigned(ui);
return 0;
}
经过多次反复,答案似乎是没有标准的方法来做这件事。选项是将
uint8\u t
读取为uint16\u t
或std::string
,然后将这些值转换为uint8\u t
:
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
uint8_t ui;
uint16_t tmp;
std::stringstream ss("46");
ss >> tmp;
ui = static_cast<uint8_t>(tmp);
cout << unsigned(ui);
return 0;
}
#包括
#包括
使用名称空间std;
int main()
{
uint8_t ui;
uint16_t tmp;
标准:stringstream ss(“46”);
ss>>tmp;
ui=静态(tmp);
cout如果您想以格式化的方式阅读,请不要使用char
或无符号char
(uint8\t)。您的示例代码及其结果是预期的行为
我们可以从中看到
template
基本流和运算符>>(基本流和st、无符号字符和ch);
这会“执行字符输入操作”
52
是“4”的ascii码。这意味着stringstream
只读取了一个字节,仍然可以读取“6”
因此,如果您希望以所需的方式工作,您应该为sstream::operator>
使用2字节或更大的整数类型,然后将其转换为uint8\t
——这正是您自我回答的方式
下面是这些重载的参考。
您可以为uint8\u t
重载输入运算符>
,例如:
std::stringstream& operator>>(std::stringstream& str, uint8_t& num) {
uint16_t temp;
str >> temp;
/* constexpr */ auto max = std::numeric_limits<uint8_t>::max();
num = std::min(temp, (uint16_t)max);
if (temp > max) str.setstate(std::ios::failbit);
return str;
}
std::stringstream和操作符>>(std::stringstream和str,uint8\u t&num){
uint16温度;
str>>温度;
/*constexpr*/auto max=std::numeric_limits::max();
num=标准::最小值(温度,(uint16_t)最大值);
if(temp>max)str.setstate(std::ios::failbit);
返回str;
}
现场演示:
说实话,我不确定这样的解决方案是否没有问题。有经验的人可能会澄清
更新
请注意,此解决方案通常不适用于std::basic_istream
(以及它的实例std::istream
),因为有一个重载的操作符>
用于无符号字符
:。行为将取决于uint8\u t
的实现方式。读取两个字节并通过std::stoi
解析它们?这是一个丑陋的解决方案。我知道它。@freakish-不是OP,而是自己创建一个字符串并解析它,而不是溪流(它的工作对象)似乎不对劲。你的笔记对我来说没有意义-你可以阅读uint16\u t
,从中转换,再也不用它了…当然,也有一些范围检查和流状态无效。@bruno-但是由于std::uint8\u t
是作为数字类型而不是字符发布的,这是一个问题。我不会真的把这称为“答案”,但这是非常有用的信息。这看起来很好。如果你把它放在一个匿名名称空间中,那么我想任何损害都是有限的。尽管我刚才问了stringstreams,我想你可以很容易地将它更改为istream
,然后覆盖所有输入流。@bremen_matt它没有看起来很简单。看这里:。编译器显然优先于ui
到char
的简单隐式转换,然后通过从派生到基的转换将str
与ss
配对。不确定如何解决此问题。@DanielLangr“编译器显然优先于ui
到char的简单隐式转换。"–这种隐式转换不适用于引用。但是,流的std::operator>
有一个无符号字符&
重载。我不确定是什么原因导致明显的歧义得到了有利于std
版本的解决,但高度怀疑libstdc++中的以下专门化:extern模板istream&operator>>(istream&,unsigned char&)
–我想这表明对标准函数进行模糊重载是一个非常糟糕的主意。@ArneVogel哦,现在明白你的意思了。我之前没有提到()。此解决方案可能非常脆弱。我会在答案中添加一个注释。
std::stringstream& operator>>(std::stringstream& str, uint8_t& num) {
uint16_t temp;
str >> temp;
/* constexpr */ auto max = std::numeric_limits<uint8_t>::max();
num = std::min(temp, (uint16_t)max);
if (temp > max) str.setstate(std::ios::failbit);
return str;
}