istringstream十进制整数输入为8位类型

时间:2014-08-10 16:05:51

标签: c++ stringstream

此:

#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位类型,还是必须使用中间商店?

5 个答案:

答案 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,这就是你的代码失败的原因。

注意:

  • 输出会遇到同样的问题。
  • 不要使用C风格的演员表,它们几乎只会导致错误。
  • 在输入操作无效之前检查EOF,您需要在之后检查失败。

答案 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>

https://www.cplusplus.com/reference/cinttypes/

https://www.cplusplus.com/reference/cstdio/printf/