-1

Having this:

#include <iostream>
#include <vector>
#include <istream>

using namespace std;

void read_vector(istream &in, vector<double> &vec)
{
    if (in) //check wheter !in.fail() => but how can "cin" have error status??
    {
        vec.clear(); //also, clear the vector (general function)
        double tmp;
        while (in >> tmp)
        {
            vec.push_back(tmp);
        }
        in.clear(); //should be there any error?
    }
}

int main()
{
    double a, b;
    vector<double> vec;
    while (cin >> a >> b)
        ;
    read_vector(cin, vec);

    for (int i = 0; i < vec.size(); i++)
    {
        cout << vec[i] << ' ';
    }
    cout << endl;
    return 0;
}

I compile and try to give test values:

$./a.out 
$1.2 3.4 5.6 7.8
$

NO output. the 1.2 should be saved to variable a, the 3.4 should be saved to variable b, and the rest stored to vector (via function read_vector). I think since it is in while() the bool condition of istream is still true.

  1. What are condition to make istream false (I know of wrong value, EOF, or other signal).

  2. Please give some practical example of good(), fail(), bad(), operator bool and operator! -> according to https://en.cppreference.com/w/cpp/io/basic_ios/operator_bool

  3. But there could be no "wrong" value (or other then type double) - how will the cin recognize to stop input to operands (a,b), make the cin wrong, and then continue to next function read_vector (so it eventually will populate the vector and I could see the result from the for loop)

milanHrabos
  • 2,010
  • 3
  • 11
  • 45
  • the usual way is `std::istream_iterator iit(std::cin); std::vector vec(iit, {});` – Mooing Duck Jul 07 '20 at 22:23
  • @Mooking, I do not get it, how is iterator connected with the istream, and what did you write, only some strange function declarations – milanHrabos Jul 07 '20 at 22:26
  • 1
    When you are testing you are passing the data as command line arguments, not as input. Try this instead: $./a.out < 1.2 3.4 5.6 7.8 – Ian4264 Jul 07 '20 at 22:32
  • The first statement constructs a `std::istream_iterator` named `iit`, and gives it the parameter `std::cin`, which is the stream that the iterator will read from. A `std::istream_iterator` constructed with no parameters `{}` means "as long as you can". Then I constructed a vector `vec` from the first iterator until the last iterator, so it reads doubles until the end of the stream or invalid data. Same as your `read_vector` method. – Mooing Duck Jul 07 '20 at 22:33
  • When you are testing you are passing the data as command line arguments, not as input. Try this instead: `$echo "1.2 3.4 5.6 7.8" | ./a.out` – Eljay Jul 07 '20 at 22:42
  • @Ian4264, sorry I editted it - I have not passed it as arguments, but as values to `cin`, see edits – milanHrabos Jul 07 '20 at 22:42
  • @Eljay the same, see edits, do not help – milanHrabos Jul 07 '20 at 22:43
  • @MooingDuck can you please provide a link where this is used in practise (an example), as you claim it is "the usual way"? – milanHrabos Jul 07 '20 at 22:47
  • 2
    The problem with "The Usual Way" is it's weakly documented because it's kind of assumed you already know it. For example, [here's me a few hours ago recommending it in a different question](https://stackoverflow.com/questions/62779418/how-to-construct-a-vector-from-a-line-of-an-unknown-number-of-int-c/62779683#comment111020035_62779683), complete with link to documentation and usage example. – user4581301 Jul 07 '20 at 22:58
  • @user4581301 thanks – milanHrabos Jul 07 '20 at 23:11

1 Answers1

0
while (cin >> a >> b)
        ;

This reads into a and b.

… then it reads into a and b again.

… and it continues to do this until the stream runs out of data.

That's because you put it in a loop.

Unsurprisingly, after the loop ends (by cin getting its error bits set), you cannot extract more data. Clearing the error bits is possible but you still have no more data to read.

I don't think you meant for a loop here; just write:

cin >> a >> b;
Asteroids With Wings
  • 17,071
  • 2
  • 21
  • 35