0

as ever I'm fairly new to C++ and I'm not exactly up with the lingo yet either so I apologize for sounding vague in advance!

My problem is I'm struggling to see why my while loop seems to stop the rest of my methods in my overloaded operator function;

#include "sample.h" #include <iostream> #include <vector> #include <cstdlib> using namespace std; sample::sample(vector<double> doubles){} sample::sample() {} ostream& operator<< (ostream &out, sample &sample) { out << "<" << sample.n << ":"; return out; } istream& operator>> (istream &in, sample &sample) { char firstChar; in >> firstChar; if(firstChar != '<'){ cout << "You've not entered the data in a valid format,please try again!1 \n"; exit(1); } int n; in >> n; sample.n = n; char nextChar; in >> nextChar; if(nextChar != ':'){ cout << "You've not entered the data in a valid format,please try again!2 \n"; exit(1); } vector<double> doubles; double number; while (in >> number){ doubles.push_back(number); cout << in << " " << number; } in >> lastChar; return in; } int main(void) { sample s; while (cin >> s){ cout << s << "\n"; } if (cin.bad()) cerr << "\nBad input\n\n"; return 0; } 

My input would be something like;

<6: 10.3 50 69.9 >

I'm trying to get all the doubles after the ':' into a vector, which I can do if they're ints but once a '.' is entered it seems to stop.

If I only put integers in, it also seems to stop after the while(in >> number) has finished finding all the numbers, which is fine but the cout<< command in my main function doesn't seem to work!

Where have I gone wrong?

0

2 Answers 2

1

You have to obey the standard stream idioms: every stream is implicitly convertible to a bool (or void pointer) to allow a check like if (in >> n) to see if the operation succeeded. So first of all you have to make sure that your operator conforms to this (by ensuring that the stream is "good" if the extraction succeeded).

Second, when you write a loop like while (in >> x) { /*...*/ }, then after the loop terminates, you already know that your stream is no longer good. So you'll have to call clear() on it before returning it.

Maybe something like this:

std::istream& operator>> (std::istream &in, sample &sample) { char c; int n; double d; std::vector<double> vd; if (!(in >> c)) { return in; } // input error if (c != '>') { in.setstate(std::ios::bad); return in; } // format error if (!(in >> n)) { return in; } // input error if (!(in >> c)) { return in; } // input error if (c != ':') { in.setstate(std::ios::bad); return in; } // format error while (in >> d) { vd.push_back(d); } in.clear(); if (!(in >> c)) { return in; } // input error if (c != '>') { in.setstate(std::ios::bad); return in; } // format error state.n = n; state.data.swap(vd); return in; } 

Note that we only modify the sample object if the entire input operation succeeded.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks Kerrek, I have a better understanding but confused as to what the clear method actually does?! I'm trying to get how it goes from the numbers part of my data onto the last character when you call a clear function?!
It doesn't "go" at all; clear just resets the error flags so that the next extraction operation will be performed at all (no extraction is performed on a stream with error).
Awesome, should've really presumed that! Thanks for your help again!
0
cout << in << " " << number; 

you probably meant

cout << " " << number; 

or something

1 Comment

Sorry anders, that as a desperate bit of code to see what it picked up when entering the numbers into the vector, I should of deleted that out of the code when I pasted it here!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.