istringstream decimal integer input to 8-bit type

本小妞迷上赌 提交于 2019-12-01 19:52:54

You have to use an intermediate type or do the parsing yourself. All char-types (char, signed char and unsigned char) are treated as text elements, not integers. int8_t is probably just a typedef for one of them, which is why your code fails.

Note:

  • The output will suffer from the same issues.
  • Don't use C-style casts, they almost only cause errors.
  • Checking for EOF before an input operation is useless, you need to check for failure afterwards instead.

There is no built-in 8-bit type; you're using an alias for signed char and IOStreams will always extract a single ASCII letter when you do formatted input into any kind of char.

So, yes, use an intermediary store, or wrap int8_t in a new class that provides its own overloads for formatted I/O (which I'd consider overkill unless you have strict memory and/or performance requirements).

(Your attempt of iss >> (int)x is very confused; conversions are used on expressions you're about to take the value of, not for lvalues naming objects that you want to set the value of.)

The fundamental problem is that int8_t is normally (apparently including your case) something like: typedef char int8_t;. For better or worse, iostreams provide overloads for char that assume the content is a character instead of a number.

It's possible to avoid this, such as by defining your own class such as:

class my_int8_t {
    // ...
};

In this case, you can provide your own overloads of operator>> and operator<< for that type (that treat the content as a number instead of a character).

Once you have that, copying the data from input to output (one number per line) is probably better done something like:

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"));

Among things, this avoids a problem in your current code with detecting the end of file correctly.

#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;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!