此:
#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)或”错误:'运算符&gt;&gt;'的歧义重载''“(g ++)。
有没有办法直接将数值作为数字读入 8位类型,还是必须使用中间商店?
答案 0 :(得分:2)
没有内置的8位类型;您正在使用signed char
的别名,当您将输入格式化为任何类型的char
时,IOStream会总是提取单个ASCII字母。
所以,是的,使用中间存储,或者将int8_t
包装在一个为格式化I / O提供自身重载的新类中(除非你有严格的内存和/或性能要求)。
(您对iss >> (int)x
的尝试非常困惑;转换用于您将要获取值的表达式,而不是用于命名要设置值的对象的左值。)
答案 1 :(得分:2)
根本问题是int8_t
通常(显然包括你的情况)类似于:typedef char int8_t;
。无论好坏,iostream都为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"));
其中,这可以避免当前代码中检测到文件末尾的问题。
答案 2 :(得分:1)
您必须使用中间类型或自己进行解析。所有char类型(char,signed char和unsigned char)都被视为文本元素,而不是整数。 int8_t可能只是其中一个的typedef,这就是你的代码失败的原因。
注意:
答案 3 :(得分:1)
#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;
}
答案 4 :(得分:0)
运算符不能区分字符类型和8位有符号/无符号整数类型之间的区别,因为它们与从语言中看到的相同(如其他答案中所述),这意味着您也不能实现同时支持这两者的类/运算符
如果同时需要两者,则必须使用scanf/printf
格式的"hhu"
或PRIu8
中的<cinttypes>
: