Connecting Tech Pros Worldwide Forums | Help | Site Map

How to read this kind of file?

PengYu.UT@gmail.com
Guest
 
Posts: n/a
#1: Jul 23 '05
Hi,

Suppose I a file with the following format --- each line is either a
record or a blank line.

If it is a record, it might be of one of the following format, where
the first format means t equals 1 by default.
w h
w h t

It is very simple to read this file if it only have "w h" record or "w
h t" record. Like the following tow code segments:

ifstream in_file;
int w, h
while(in_file >> w >> h){
....
}

ifstream in_file;
int w, h, t
while(in_file >> w >> h >> t){
....
}

But it is not very straight forward to me how to read a file with both
kinds of records. Would you please help me?

Best wishes,
Peng


Rapscallion
Guest
 
Posts: n/a
#2: Jul 23 '05

re: How to read this kind of file?


PengYu.UT@gmail.com wrote:[color=blue]
> Suppose I a file with the following format --- each line is either a
> record or a blank line.
>
> If it is a record, it might be of one of the following format, where
> the first format means t equals 1 by default.
> w h
> w h t[/color]

step 1: Read the whole line with getline() or fgtes(), respectively.
step 2: Parse the line (and you'll see if it contains 0, 2, or 3
tokens).

Alan Johnson
Guest
 
Posts: n/a
#3: Jul 23 '05

re: How to read this kind of file?


PengYu.UT@gmail.com wrote:
[snip][color=blue]
> But it is not very straight forward to me how to read a file with both
> kinds of records. Would you please help me?
>
> Best wishes,
> Peng
>[/color]

My preferred method is to roll everything up into a class or struct.
With your example, the result would look something like:

#include <iostream>
#include <string>
#include <sstream>

struct record
{
int w, h, t ;

// Put constructors and other members if you want them.
} ;

std::istream &operator>>(std::istream &is, record &r)
{
int w, h, t ;
std::string s ;

if (std::getline(is, s))
{
std::istringstream ss(s) ;
if (ss >> w >> h)
{
r.w = w ;
r.h = h ;

if (ss >> t)
r.t = t ;
else
r.t = 1 ;
}
}

return is ;
}

std::ostream &operator<<(std::ostream &os, const record &r)
{
os << r.w << ' ' << r.h << ' ' << r.t ;
}



Now you can do all sorts of neat stuff. You could read the file like
you were original trying to:

record r ;
while (in_file >> r) { ... }

But you could also easily create a whole vector/list/etc from your file
in one command:

#include <vector>
#include <algorithm>
#include <iterator>
....
std::vector<record> records ;
std::copy(std::istream_iterator<record>(in_file),
std::istream_iterator<record>(),
std::back_inserter(records)) ;


Or my favorite, you could create a function object to process a record,
and then process the whole file with one command:

class process_record
{
public :
void operator()(const record &r)
{
// Do some record processing.
std::cout << "I just processed record: "
<< r << std::endl ;
}
} ;

....

std::for_each(std::istream_iterator<record>(in_fil e),
std::istream_iterator<record>(),
process_record()) ;


Anyhow, I hope this at least gives you some ideas of how to approach
your problem. Good luck!

-Alan
PengYu.UT@gmail.com
Guest
 
Posts: n/a
#4: Jul 23 '05

re: How to read this kind of file?


Thank you for the detailed example.

Peng

PengYu.UT@gmail.com
Guest
 
Posts: n/a
#5: Jul 23 '05

re: How to read this kind of file?


I feel there are several getline functions. Is the following webpage
describe the one that you use?
http://www.cppreference.com/cppio/getline.html

I'm confused why the return value of "istream&" can be used as the
condition. Or do I read the wrong definition?

Best wishes,
Peng

Alan Johnson
Guest
 
Posts: n/a
#6: Jul 23 '05

re: How to read this kind of file?


PengYu.UT@gmail.com wrote:[color=blue]
> I feel there are several getline functions. Is the following webpage
> describe the one that you use?
> http://www.cppreference.com/cppio/getline.html
>
> I'm confused why the return value of "istream&" can be used as the
> condition. Or do I read the wrong definition?
>
> Best wishes,
> Peng
>[/color]

Yes. That is the one used in my example.

The standard defines two functions named "getline". One is actually a
member function of the basic_istream template class. It let's you do
things along the lines of:

char buffer[1024] ;
cin.getline(buffer, 1024, '\n') ;

The other, used in the example code in previous posts, is defined as
part of the "Strings library" (clause 21 of the standard). It is
designed specifically to read from a stream into a std::string (or
std::wstring) object. The advantage of this form is that you don't have
to guess at how long a line is. It will keep reading into your string
object (which will keep resizing itself when appropriate) until you've
reached an end of line. The disadvantage, of course, is that you have
to use a string object, which may or may not be appropriate for your
task. For tasks that involve processing lines of text (like the one you
posed) this is usually the easiest approach (in my opinion).

-Alan
Alan Johnson
Guest
 
Posts: n/a
#7: Jul 23 '05

re: How to read this kind of file?


Alan Johnson wrote:[color=blue]
> PengYu.UT@gmail.com wrote:
>[color=green]
>> I feel there are several getline functions. Is the following webpage
>> describe the one that you use?
>> http://www.cppreference.com/cppio/getline.html
>>
>> I'm confused why the return value of "istream&" can be used as the
>> condition. Or do I read the wrong definition?
>>
>> Best wishes,
>> Peng
>>[/color]
>
> Yes. That is the one used in my example.
>
> The standard defines two functions named "getline". One is actually a
> member function of the basic_istream template class. It let's you do
> things along the lines of:
>
> char buffer[1024] ;
> cin.getline(buffer, 1024, '\n') ;
>
> The other, used in the example code in previous posts, is defined as
> part of the "Strings library" (clause 21 of the standard). It is
> designed specifically to read from a stream into a std::string (or
> std::wstring) object. The advantage of this form is that you don't have
> to guess at how long a line is. It will keep reading into your string
> object (which will keep resizing itself when appropriate) until you've
> reached an end of line. The disadvantage, of course, is that you have
> to use a string object, which may or may not be appropriate for your
> task. For tasks that involve processing lines of text (like the one you
> posed) this is usually the easiest approach (in my opinion).
>
> -Alan[/color]

Sorry, I answered incorrectly. The "getline" documented in the link you
included is the first form I mentioned above. The getline I used in the
example is the second form.

-Alan
Closed Thread