Re: Reading items from a text file to a vector
On Nov 14, 2:00 am, zr <zvir...@gmail.com> wrote:
i need to read a text file which contains a list of items, all
of type ItemType, separated by whitespace and newlines. For
each line, there will be a vector<ItemType> object that will
store the integers read in that line. There will be a single
vector<vector<ItemType>> object that will stores all of the
vector<ItemType> objects mentioned in the previous sentence.
I wrote a quick implementation and it seems to be working, but
i would like to hear some opinions on what may be incorrect or
may be improved, especially exception and runtime error
handling. Assume that the required operator>> in code line 13
is defined.
As you've posted it, it won't compile:-). But in fact, it isn't
guaranteed to work, even with the correction to the syntax.
1 template <class ItemType>
2 void collect(istream& source, vector<vector<ItemType>>& db) {
">>" is a shift left operator, and doesn't close two open template
lists; you need "> >" (unless your compiler has already
implemented this feature of the next version of the standard).
3 while (source.good()) {
And this is an error; source.good() does NOT mean that the next
input is guaranteed to succeed. (In practice, what will
probably happen is that you'll get an extra, empty list at the
end of your results.)
4 string s;
5 getline(source, s, '\n');
6 istringstream iss(s);
7 if (iss.bad() || 0==s.size())
8 break;
9 vector<ItemType> t;
10
11 while (iss.good()) {
Same thing here. Most of the time, this will work anyway, but
if you have a line which contains trailing white space, it may
result in an additional default constructed item at the end of
the list.
12 ItemType item;
13 iss >> item;
14 t.push_back(item);
15 }
16 db.push_back(t);
17 }
18}
In general, you should always test *after* reading from a
stream, to know if the input succeeded or failed. And be wary
of the names of the status functions in the streams; they are
very misleading. (I've never found a use for good(), for
example.) Taking this into account, your code should probably
look something like:
std::string s ;
while ( std::getline( source, s ) ) {
std::istringstream iss( s ) ;
std::vector< ItemType >
t ;
ItemType item ;
while ( iss >> item ) {
t.push_back( item ) ;
}
db.push_back( t ) ;
}
In addition, you might want to think about other possible input
errors: what happens if an item in the file is misformatted.
(You can typically detect this by checking iss.eof() after the
inner loop above; if input failed and you don't have eof() or
bad(), then you have a formatting error.)
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34