字符串流十进制整数输入到 8 位类型

istringstream decimal integer input to 8-bit type

本文关键字:类型 输入 十进制 整数 字符串      更新时间:2023-10-16

This:

#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(或">错误:'运算符'的不明确重载'运算符>>'"(g++(。

有没有办法将值作为数字直接读取到 8 位类型中,还是必须使用中间存储?

没有内置的 8 位类型;您正在使用别名进行signed char,当您将格式化输入到任何类型的char时,IOStreams 将始终提取单个 ASCII 字母。

所以,是的,使用中间存储,或者int8_t包装在一个新的类中,该类为格式化的I/O提供自己的重载(除非你有严格的内存和/或性能要求,否则我认为这是矫枉过正的(。

(您的iss >> (int)x尝试非常混乱;转换用于您将要获取其值的表达式,而不是用于要设置其值的 lvalues 命名对象。

您必须使用中间类型或自己进行解析。所有字符类型(字符、有符号字符和无符号字符(都被视为文本元素,而不是整数。int8_t可能只是其中一个的 typedef,这就是您的代码失败的原因。

注意:

  • 输出将遇到相同的问题。
  • 不要使用 C 样式转换,它们几乎只会导致错误。
  • 在输入操作之前检查 EOF 是无用的,您需要在之后检查失败。

根本问题是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 位有符号/无符号整数类型,因为它们与从语言中看到的相同(如其他答案中所述(,这意味着您也无法实现支持两者的类/运算符。

如果你两者都需要,你被迫使用格式"hhu"scanf/printf,或从<cinttypes> PRIu8

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

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