2

The following program apparently shows an inconsistency when writing and reading on a std::stringstream a double set to "infinity", using std::numeric_limits<double>::infinity.

#include <string>
#include <sstream>
#include <iostream>
#include <limits>
#include <iterator>

int main() {
    std::stringstream stream;
    double d;

    // Part 1
    d=4;
    stream << d << " ";
    d=std::numeric_limits<double>::infinity();
    stream << d << " ";
    d=5;
    stream << d;
    stream.seekg(std::ios_base::beg);

    std::string s = stream.str();
    std::cout << "string : " << s << std::endl;

    // Part 2
    std::cout << "Extraction of data 1:" << std::endl;
    stream.seekp(std::ios_base::beg);
    stream >> d;
    std::cout << d << std::endl;
    stream >> d;
    std::cout << d << std::endl;
    stream >> d;
    std::cout << d << std::endl;

    // Part 3
    std::cout << "Extraction of data 2:" << std::endl;
    std::istringstream stream2(s);
    std::istream_iterator<double> iter(stream2);
    std::istream_iterator<double> eos;
    while (iter != eos)
    {
        std::cout << (*iter) << std::endl;
        iter++;
    }

    return 0;
}

See it live.

The output is

string : 4 inf 5
Extraction of data 1:
4
0
0
Extraction of data 2:
4

In part 1 a double "infinity" is written to a stringstream and the string extracted from it shows an "inf" corresponding to such an infinity.

In part 2, however, the substring "inf" is apparently extracted to 0. Moreover, the stream appears to be in a bad state, since successive extractions give again 0.

Similarly, in part 3 a istream_iterator is used to extract the doubles from the string. The iterator reaches an end-of-stream before reading "inf".

Obviously, one could easily fix the problem by extracting words instead of double and converting each of them to a "normal" double, or to std::numeric_limits<double>::infinity when a "inf" is encountered. However, this seems like reinventing the wheel, given that the standard library already contains a lot of code to extract data from a stream....

  • Why is there a difference when inserting and extracting a std::numeric_limits<double>::infinity?
  • Within the standard library, is there a possibility of extracting a double which could also be infinity, without resorting to write a function that extracts words and convert them to double?

Additional note

According to the c++ reference, std::stod and similar functions already convert "inf" to an infinite expression. Hence, it looks like std::stringstream::operator<< does not use std::stod or similar to convert a piece of string to a double.

francesco
  • 7,189
  • 7
  • 22
  • 49
  • 2
    https://en.cppreference.com/w/cpp/locale/num_get/get : _Because stage 2 filters out characters such as 'p', 'N' or 'i', the hexadecimal floating-point numbers such as "0x1.23p-10" and the strings "NaN" or "inf" may be rejected by do_get(double) even if they are valid input to strtod: this is [LWG#2381](http://cplusplus.github.io/LWG/lwg-active.html#2381)_ – Mat Jul 26 '19 at 14:21

0 Answers0