Very quick C++ I/O n00b question

C

chaoticcranium

Right now, I am reading a file line by line using getline() using this
code:

// Read file line by line, store the first 3 values on each line
in a vector and store the vector in a vector of vectors
while(getline(peakReader, line)) {
istringstream lineStr(line);
vector<int> peak(3);
if (!(lineStr >> peak[0] >> peak[1] >> peak[2])) {
cerr << "Error reading peak file; will continue
without using peaks." << endl;
usePeaks = false;
break;
}
peaks.push_back(peak);
}
peakReader is an ifstream, line is a string.

I was wondering if there is an easy way to prevent this code from
reading the last line of the file without affecting any of the other
lines. The only way I can see doing it is by opening another input
file stream, iterating line-by-line through the file to tally the
number of lines in the file, and then check for the last line by its
line number, but I feel this is a rather lame way of doing it and
there has to be something better that can be accomplished in this one
loop. Thanks in advance for your help.
 
J

Jim Langston

Right now, I am reading a file line by line using getline() using this
code:

// Read file line by line, store the first 3 values on each line
in a vector and store the vector in a vector of vectors
while(getline(peakReader, line)) {
istringstream lineStr(line);
vector<int> peak(3);
if (!(lineStr >> peak[0] >> peak[1] >> peak[2])) {
cerr << "Error reading peak file; will continue
without using peaks." << endl;
usePeaks = false;
break;
}
peaks.push_back(peak);
}
peakReader is an ifstream, line is a string.

I was wondering if there is an easy way to prevent this code from
reading the last line of the file without affecting any of the other
lines. The only way I can see doing it is by opening another input
file stream, iterating line-by-line through the file to tally the
number of lines in the file, and then check for the last line by its
line number, but I feel this is a rather lame way of doing it and
there has to be something better that can be accomplished in this one
loop. Thanks in advance for your help.

One way to handle that problem is not to store the current line each time,
but store the previous line. I.E. in pseudo code

std::string LastLine;
std::string Line;
if ( std::getline(peakReader, LastLine )
while ( std::getline( peakReader, Line )
{
// formatting here for LastLine into peak
peaks.push_back( peak );
LastLine = ThisLine;
}

There is probalby another way, but something like this is what I'd probably
use.
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

Right now, I am reading a file line by line using getline() using this
code:

// Read file line by line, store the first 3 values on each line
in a vector and store the vector in a vector of vectors
while(getline(peakReader, line)) {
istringstream lineStr(line);
vector<int> peak(3);
if (!(lineStr >> peak[0] >> peak[1] >> peak[2])) {
cerr << "Error reading peak file; will continue
without using peaks." << endl;
usePeaks = false;
break;
}
peaks.push_back(peak);
}
peakReader is an ifstream, line is a string.

I was wondering if there is an easy way to prevent this code from
reading the last line of the file without affecting any of the other
lines. The only way I can see doing it is by opening another input
file stream, iterating line-by-line through the file to tally the
number of lines in the file, and then check for the last line by its
line number, but I feel this is a rather lame way of doing it and
there has to be something better that can be accomplished in this one
loop. Thanks in advance for your help.

I was going to suggest the same solution as Jim Langstrom, so I'll just
make an observation instead. If you are always going to read read three
values from each line, using a vector to store them will be a bit
wasteful (unless you'll add more elements later). Instead use a structt:

struct MyValues {
int v1, v2, v3;
};

std::vector<MyValues> peaks;

.....

MyValues val;
if (!(lineStr >> val.v1 >> val.v2 >> val.v3 )) {

.....
 
B

BobR

Right now, I am reading a file line by line using getline() using this
code:

// Read file line by line, store the first 3 values on each line
in a vector and store the vector in a vector of vectors
while(getline(peakReader, line)) {
istringstream lineStr(line);
vector<int> peak(3);
if (!(lineStr >> peak[0] >> peak[1] >> peak[2])) {
cerr << "Error reading peak file; will continue
without using peaks." << endl;
usePeaks = false;
break;
}
peaks.push_back(peak);
}
peakReader is an ifstream, line is a string.

I was wondering if there is an easy way to prevent this code from
reading the last line of the file without affecting any of the other
lines. The only way I can see doing it is by opening another input
file stream, iterating line-by-line through the file to tally the
number of lines in the file, and then check for the last line by its
line number, but I feel this is a rather lame way of doing it and
there has to be something better that can be accomplished in this one
loop. Thanks in advance for your help.

[ in case you don't want to use Jim's suggestion for some reason.]
Put a unique character in the first position of the last line, and test for
it.
Since you are reading in numbers, use something that is not a number.

// - in file -
$ this is the last line.
// ------

while( peakReader.peek() != '$' && getline(peakReader, line) ){
// ....
} // while()

The 'peek()' will read a char without moveing the 'get pointer' in the file.
The 'while()' above will depend on 'getline()' leaveing the 'get pointer' at
the start of the next line ( so, don't do anything like a 'seekg() that
would move the pointer.)

or something like:

while( std::isdigit( peakReader.peek() ) && ....){....} // <cctype>

.... might work, depends on what the file contains (format).

Just some ideas, not tested.
 
F

Frank Birbacher

Hi!
[ in case you don't want to use Jim's suggestion for some reason.]
Put a unique character in the first position of the last line, and test for
it.
Since you are reading in numbers, use something that is not a number.

If he was to generate the file in the first place he could as well just
put the line at the beginning of the file :)

Frank
 
J

Jerry Coffin

[ ... ]
I was wondering if there is an easy way to prevent this code from
reading the last line of the file without affecting any of the other
lines.

The easiest way is probably to read the last line, but not process it,
something like this:

// warning: untested code
std::string prev_line, curr_line;

std::getline(peakReader, prev_line);

while (getline(peakReader, curr_line) {
peaks.push_back(process(prev_line));
prev_line = curr_line;
}
 

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

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top