Stream input, critique my code?

D

Donald Canton

Hi,

My goal is to read a text file consisting of lines containing
someone's name followed by one or more numeric values. All fields are
tab-delimited. The name could be in any one of the following formats:

John Doe
J. Doe
John H. Doe

and will always be followed by at least one tab character. Here's the
code:

#include <fstream>
#include <istream>
#include <iostream>
#include <string>

int main()
{
std::ifstream inputfile("data.txt");
if( !inputfile ) {
std::cerr << "Can't open file: " << '\n';
return -1;
}
std::istream& input = inputfile;
std::string name;
double value;

while ( std::getline(input, name, '\t') )
{
//do something with name, then read values
while ( input >> value ) {
//do something with value
}
input.clear(); //end of values, reset stream
}
return 0; //end of input
}

Are there any pitfalls in doing it this way? Suggestions?

Thanks in advance,

Donald Canton
 
J

John Harrison

Donald Canton said:
Hi,

My goal is to read a text file consisting of lines containing
someone's name followed by one or more numeric values. All fields are
tab-delimited. The name could be in any one of the following formats:

John Doe
J. Doe
John H. Doe

and will always be followed by at least one tab character. Here's the
code:

#include <fstream>
#include <istream>
#include <iostream>
#include <string>

int main()
{
std::ifstream inputfile("data.txt");
if( !inputfile ) {
std::cerr << "Can't open file: " << '\n';
return -1;
}
std::istream& input = inputfile;

Why the above? Just use inputfile directly.
std::string name;
double value;

while ( std::getline(input, name, '\t') )
{
//do something with name, then read values
while ( input >> value ) {
//do something with value
}
input.clear(); //end of values, reset stream
}
return 0; //end of input
}

Are there any pitfalls in doing it this way? Suggestions?

It seems to work, but its tricky code that relies on the details on the
iostream library and the format of your input file. For instance it will be
defeated by a name that begins with a digit. You might think that will never
happen, but I know from experience you get all sorts of strange things in
large data sets (I remember the occasion when my code was defeated by
someone who had a superscripted digit in the middle of their name).

I would rather see code that reflects your requirements directly. I.e.

while (read a line)
{
split line at first tab into 'name' and 'values'
get name from 'name' (trim whitespace?)
create stringstream from 'values'
while (read a value)
{
do something with value
}
}

It might be more long winded but its a simple translation of your
requirements into code, with no trickery.

john
 
D

Donald Canton

John Harrison said:
Why the above? Just use inputfile directly.


It seems to work, but its tricky code that relies on the details on the
iostream library and the format of your input file. For instance it will be
defeated by a name that begins with a digit. You might think that will never
happen, but I know from experience you get all sorts of strange things in
large data sets (I remember the occasion when my code was defeated by
someone who had a superscripted digit in the middle of their name).

I would rather see code that reflects your requirements directly. I.e.

while (read a line)
{
split line at first tab into 'name' and 'values'
get name from 'name' (trim whitespace?)
create stringstream from 'values'
while (read a value)
{
do something with value
}
}

It might be more long winded but its a simple translation of your
requirements into code, with no trickery.

john

Thanks. I've made some changes per your recommendations.

dc
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,817
Latest member
DicWeils

Latest Threads

Top