C++ istringstream behavior and its alternative

There is a function hexstr_to_str reading from memory(not a file, not a cin) a text stream of the form "01 03 10 fa", and writing to std:: string containing \x01\x03\x10\xfa. The problem with reading from the integer stream is that after reading the last number, the flag in the failbit stream is set. Is there an alternative to istringstream, or after reading each number from the stream, do you need to check for the end of the string, for example, via peek ()? Are there any easier solutions?

#include <iostream>
#include <sstream>

ssize_t hexstr_to_str(std::string &destination, std::istringstream &stream_source)
{
    std::ios::fmtflags 
              old_flags = stream_source.setf(std::ios::hex, std::ios::basefield);
    size_t    count     = 0;
    int       symbol    = -1;
    destination.clear();
    while ( stream_source >> symbol ) //добавление  && !stream_source.eof() результата не дало. 
    {
        destination += symbol;
        ++count;
    }
    stream_source.setf(old_flags);
    std::cout << (stream_source.rdstate() & (stream_source.failbit | stream_source.badbit))<<"\n";
    return  !(stream_source.rdstate() & (stream_source.failbit | stream_source.badbit)) ? count : -count;
}



int main()
{
    std::string hb_str;
    //std::cout << hexstr_to_str(hello_str, std::istringstream(cstr_hex_hello));
    hexstr_to_str(hb_str, std::istringstream("10 20 af 30"));

    return 0;
}
Author: borat_brata, 2016-09-22

2 answers

Why do you consider the presence of failbit a problem?

Forget about it, this is normal behavior at the end of the line.

Check eof - if the end of the string is reached, the parsing of the string was successful. If it is not reached, it means that there was an error:

return stream_source.eof() ? count : -count;
 0
Author: Pavel Mayorov, 2016-09-22 11:13:20

Just in case (had fun)

using namespace std;

string get_xstr (string str, long *errpos) {
  if (errpos)
    *errpos = -1;
  istringstream istr(str);
  ostringstream ostr;
  long x, curpos;
  istr.setf(std::ios::hex, std::ios::basefield);
  ostr.setf(std::ios::hex, std::ios::basefield);

  while (istr >> x) {
    curpos = istr.tellg();
    ostr << "\\x" << x;
  }
  if (!istr.eof() && errpos) 
    *errpos = curpos;

  return ostr.str();
}

Note that the possible position of the error in the string has to be taken in a loop, since the behavior of .tellg() is similar to the delirium with failbit.

 0
Author: avp, 2016-09-22 12:10:04