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

问题描述 投票:5回答:5

这个。

#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

Casting iss >> (int)x (我最初尝试用 char)给我"错误: 二进制表达式('istringstream'(又名'basic_istringstream')和'int')的操作数无效" (clang)或"错误: 'operator>>'的重载有歧义" (g++).

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

c++ stringstream
5个回答
2
投票

你必须使用一个中间类型或者自己做解析。所有的char类型(char、signed char和unsigned char)都被视为文本元素,而不是整数。int8_t可能只是其中之一的类型定义,这就是为什么你的代码失败了。

请注意。

  • 输出也会出现同样的问题.
  • 不要使用C-style的casts,它们几乎只会导致错误。
  • 在输入操作前检查EOF是没有用的,你需要在操作后检查失败。

3
投票

没有内置的8位类型;你使用了一个别名的 signed char 和IOStreams将 始终 当你在任何一种格式化的输入中提取一个ASCII字母的时候,你就会发现,你的输入是一个很好的例子。char.

所以,是的,使用一个中间存储,或者包裹一个中间存储。int8_t 在一个新的类中,它为格式化的IO提供了自己的重载(我认为这是矫枉过正的,除非你有严格的内存或性能要求)。

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


2
投票

基本的问题是 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"));

其中,这就避免了你当前代码中的一个问题,即正确检测文件的结束。


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;
}

0
投票

运算符无法区分字符类型和8位signedunsigned整数类型的区别,因为它们和从语言中看到的是一样的(如其他答案中提到的),这意味着你也无法实现一个同时支持这两种类型的类运算符。

如果你需要这两种类型,你就不得不使用 scanf/printf 格式为 "hhu"PRIu8<cinttypes>:

https:/www.cplusplus.comreferencecinttypes

https:/www.cplusplus.comreferencecstdioprintf

© www.soinside.com 2019 - 2024. All rights reserved.