繁体   English   中英

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

[英]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,这就是您的代码失败的原因。

笔记:

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

如果你既需要,你不得不使用scanf/printf与格式"hhu" ,或PRIu8<cinttypes>

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM