How to read this kind of file?

Discussion in 'C++' started by PengYu.UT@gmail.com, Jun 4, 2005.

  1. Guest

    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
     
    , Jun 4, 2005
    #1
    1. Advertising

  2. Rapscallion Guest

    wrote:
    > 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


    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).
     
    Rapscallion, Jun 4, 2005
    #2
    1. Advertising

  3. Alan Johnson Guest

    wrote:
    [snip]
    > 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
    >


    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::eek:stream &operator<<(std::eek:stream &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_file),
    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
     
    Alan Johnson, Jun 4, 2005
    #3
  4. Guest

    Thank you for the detailed example.

    Peng
     
    , Jun 4, 2005
    #4
  5. Guest

    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
     
    , Jun 4, 2005
    #5
  6. Alan Johnson Guest

    wrote:
    > 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
    >


    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, Jun 5, 2005
    #6
  7. Alan Johnson Guest

    Alan Johnson wrote:
    > wrote:
    >
    >> 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
    >>

    >
    > 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


    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
     
    Alan Johnson, Jun 5, 2005
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    0
    Views:
    419
  2. Davmagic .Com

    What Kind of File is this?

    Davmagic .Com, Jun 29, 2004, in forum: HTML
    Replies:
    2
    Views:
    477
    Whitecrest
    Jun 30, 2004
  3. yezi

    How to read such kind of file format ?

    yezi, Oct 27, 2005, in forum: C Programming
    Replies:
    5
    Views:
    443
    Flash Gordon
    Oct 28, 2005
  4. Sreejith K
    Replies:
    24
    Views:
    1,087
    Sreejith K
    Mar 24, 2009
  5. Alex Dowad
    Replies:
    4
    Views:
    314
    Michel Demazure
    May 1, 2010
Loading...

Share This Page