[英]istringstream decimal integer input to 8-bit type
这个:
#include <iostream>
#include <sstream>
#include <inttypes.h>
using namespace std;
int main (void) {
istringstream iss("123 42");
int8_t x;
while (iss >> x) {
cout << x << endl;
}
return 0;
}
产生:
1
2
3
4
2
但我想要:
123
42
铸造iss >> (int)x
(我最初用char
尝试过)给了我“错误:二进制表达式的无效操作数('istringstream'(又名'basic_istringstream')和'int')”(clang)或“错误: 'operator>>'" (g++) 的不明确重载。
有没有办法将值作为数字直接读入8 位类型,还是必须使用中间存储?
没有内置的 8 位类型; 您正在使用带signed char
的别名,当您对任何类型的char
进行格式化输入时,IOStreams 将始终提取单个 ASCII 字母。
因此,是的,使用中间存储,或将int8_t
包装在一个新类中,该类为格式化的 I/O 提供自己的重载(除非您有严格的内存和/或性能要求,否则我认为这有点矫枉过正)。
(您对iss >> (int)x
尝试非常混乱;转换用于您将要取其值的表达式,而不是用于命名要设置其值的对象的左值。)
您必须使用中间类型或自己进行解析。 所有字符类型(字符、有符号字符和无符号字符)都被视为文本元素,而不是整数。 int8_t 可能只是其中一个的 typedef,这就是您的代码失败的原因。
笔记:
根本问题是int8_t
通常(显然包括您的情况)类似于: typedef char int8_t;
. 不管是好是坏,iostreams 为char
提供了重载,假设内容是字符而不是数字。
可以避免这种情况,例如通过定义您自己的类,例如:
class my_int8_t {
// ...
};
在这种情况下,您可以为该类型提供自己的operator>>
和operator<<
重载(将内容视为数字而不是字符)。
完成后,将数据从输入复制到输出(每行一个数字)可能会更好地执行以下操作:
std::copy(std::istream_iterator<my_int8_t>(std::cin),
std::istream_iterator<my_int8_t>(),
std::ostream_iterator<my_int8_t>(std::cout, "\n"));
其中,这避免了当前代码中正确检测文件结尾的问题。
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
typedef unsigned char uint8_t;
class exstringstream : public stringstream
{
public:
exstringstream(const string& s)
:stringstream(s)
{
}
friend exstringstream& operator >> (exstringstream&, uint8_t& t);
};
exstringstream& operator >> (exstringstream& ss, uint8_t& t)
{
unsigned int val;
stringstream& s = ss;
s >> val;
t = static_cast<uint8_t>(val);
return ss;
}
int main()
{
string str("123 45");
exstringstream ss(str);
uint8_t a, b;
ss >> a >> b;
cout << a << " " << b << endl;
return 0;
}
运算符无法区分字符类型和 8 位有符号/无符号整数类型,因为它们与从语言中看到的相同(如其他答案中所述),这意味着您也无法实现支持两者的类/运算符。
如果你既需要,你不得不使用scanf/printf
与格式"hhu"
,或PRIu8
从<cinttypes>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.