c++ - How to use input stream overloading to insert item to map member in class? -
i have c++ class question
hold data file questions.txt
of multiple choice questions , answers:
update: have updated &operator>> operator overload have one:
- it insert first multiple choice question of 2 multiple choice questions"read first question "
data in file questions.txt:
a programming language used in course? 3 1. c 2. pascal 3. c++ 4. assembly compiler can use compile programs in course? 4 1. dev-c++ 2. borland c++builder 3. microsoft visual c++ 4. of above
i'm trying insert multiple answers map. want ask how overload operator>>
iterate on multiple answers insert them map:
#include <string> #include <iostream> #include <sstream> #include <map> using namespace std; class question { string question; int correctindex; map<int,string> answers; friend std::istream &operator>>(std::istream &is, question &q) { getline(is, q.question, '?'); // stops @ '?' is>> q.correctindex; string line; while (getline(is, line) && line.empty()) // skip leading blank lines ; while (getline(is,line) && !line.empty()) // read until blank line { int id; string ans; char pt; stringstream sst(line); // parse line; sst>>id>>pt; // take number , following point if (!sst || id==0 || pt!='.') cout << "parsing error on: "<<line<<endl; else { getline (sst, ans); q.answers[id] = ans; } } return is; } }; int main() { ifstream readfile("questions.txt");//file stream vector<question> questions((istream_iterator<question>(readfile)), istream_iterator<question>()); }
there 2 issues code: skipping first answer , reading through end of file.
in pair of loops:
while (getline(is, line) && line.empty()) // skip leading blank lines ; while (getline(is,line) && !line.empty()) // read until blank line {
the first non-empty line
terminate first loop, call getline()
again without reading of contents. skips first answers choice. you'll want make sure don't call getline()
first time. like...
// skip leading blank lines while (getline(is, line) && line.empty()) { ; } (; && !line.empty(); getline(is, line)) { // ... }
but second , bigger problem if read through end of file (as code right now) last operator>>
cause istream
eof()
, disregard last question
have streamed. tricky since have variable-length input stream - don't know when we've run out of input until we've run out of input.
thankfully, can quite bit simpler. first, instead of reading off end of input trigger error, we'll use first read cause stop:
friend std::istream &operator>>(std::istream &is, question &q) { if (!getline(is, q.question, '?')) { // stops @ '?' return is; }
this way, if hit eof early, stop early. rest, can reading using skipws()
. instead of manually looping through empty lines (which hard right, per initial bug), can let operator>>
skipping ahead.
when run out of things read, out of error flags - since don't want fail()
(if try read next index , it's next question) or eof()
(we're done) triggered.
altogether:
friend std::istream &operator>>(std::istream &is, question &q) { if (!getline(is, q.question, '?')) { // stops @ '?' return is; } >> q.correctindex; int id; char pt; string ans; >> skipws; while (is >> id >> pt && getline(is, ans)) { q.answers[id] = ans; } // keep bad bit, clear rest is.clear(is.rdstate() & ios::badbit); return is; }
now that's little incomplete. perhaps want indicate error if don't read answers
matched correctindex
? in case, set ios::failbit
too.
Comments
Post a Comment