Topic: How do I read a text file into a list<string> easily?


Author: LLeweLLyn <llewelly.at@xmission.dot.com>
Date: 21 Mar 2003 11:52:38 -0500
Raw View
Hyman Rosen <hyrosen@mail.com> writes:

> LLeweLLyn wrote:
>  > istream& operator>>(istream& lhs,foo& rhs)
>  >   {getline(lhs,rhs.s,'\n');}
>
> You mean
>       istream &operator>>(istream &lhs, foo &rhs)
>       { return getline(lhs, rhs.s); }

No, I would have spent some quality time with the debugger - I'd
    completely forgotten the missing return. Thank you.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kanze@gabi-soft.de (James Kanze)
Date: 20 Mar 2003 04:14:59 -0500
Raw View
musiphil@bawi.org (KIM Seungbeom) wrote in message
news:<bd47bb0e.0303180915.3fbfbe7b@posting.google.com>...
> jpotter@falcon.lhup.edu (John Potter) wrote in message
> news:<5t83p6$9qr$1@pigpen.csrlink.net>...
> > "Bennett Smith" <BennettSmith@acm.org> wrote:

> > > I'm new to using the Standard C++ Library and am having some
> > > trouble with it.  I want to read in a text file and store the
> > > contents in a list<string> where each line of the file is in a
> > > string.  I cannot figure out an easy way to do this.  Could
> > > someone give me some pointers?

> > #include <iostream>
> > #include <fstream>
> > #include <string>
> > #include <list>
> > int main (int argc, char* argv[]) {  // errors ignored for simplicity
> >  ifstream f(argv[1]);
> >  list<string> l;
> >  string s;
> >  while (getline(f, s))
> >   l.push_back(s);
> >  doSomethingWith(l);
> >  }

> > That seems easy enough to me.

> > Since this is comp.std.c++, I might be missing something in the
> > question.  Is there a way to use a standard library algorithm to
> > replace s and the following two lines without defining some new
> > class?  Is there (should there be) an istream_line_iterator?  That
> > would allow use of copy.  Some other subtlety that I missed?

> This message is quite old, but I'd like to ask again: Is there a way
> to use a standard library algorithm to replace this explicit loop with
> std::copy?

>  string s;
>  while (getline(f, s)) l.push_back(s);

Only by introducing an additional class. I've found this useful in
certain contexts -- there is often a certain logic in having a class
"Line", which contains a string with the line (but which might also
contain additional information, like the line number): if nothing else,
it says loudly and clearly that this string is an entire line.

With the additional class, of course, you define:

    std::istream&
    operator>>( std::istream& source, Line& dest )
    {
        getline( source, dest ) ;
        return source ;
    }

and you can then write something like:

    std::list< Line > l ;
    std::copy( std::istream_iterator( f ),
               std::istream_iterator(),
               std::back_inserter( l ) ) ;

--
James Kanze             GABI Software             mailto:kanze@gabi-soft.fr
Conseils en informatique orient   e objet/
                           Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, T   l. : +33 (0)1 30 23 45 16
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Early Ehlinger" <early@respower.com>
Date: 20 Mar 03 16:25:52 GMT
Raw View
"LLeweLLyn" <llewelly.at@xmission.dot.com> wrote:
> (#includes, usings, and standards conformance left as an exercise
>     for the reader. :-)
>
> The auxillary struct and operator>> are longer than the while loop,
>     >> and IMO less comprehensible. That is, the above is perhaps a
>     'solution' but not an improvement.

I think you might be giving your solution short shrift.  If you change the
name of foo to something a little more descriptive, say "line", then it
makes a little more sense:

int main(int argc,char* argv[])
    {
    ifstream f(argv[1]);
    list<string> l;
    string s;

    copy
        (istream_iterator<line>(f)
        ,istream_iterator<line>()
        ,back_inserter(l));
        // copy the file line-by-line into l.

    copy
        (l.begin()
        ,l.end()
        ,ostream_iterator<string>(cout,"\n"));
    }

Furthermore, it becomes something that can be used in other situations,
avoiding the annoying getline idiom:

int main(int argc, char** argv )
    {
    line l;
    int i;
    float f;
    ifstream file(argv[1]);
    file >> l >> i >> f >> l;
        /* reads a file whose format is
            * a line, followed by
            * an int
            * a float
            * and another line. */
    }

Thanks for the solution!  I'll be adding it to my library, anyway :)

--
-- Early Ehlinger CEO, ResPower Inc - Toll-Free : 866-737-7697
-- www.respower.com -- 500+ GHz Supercomputer Starting At USD$0.50/GHz*Hour






      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]




Author: Hyman Rosen <hyrosen@mail.com>
Date: 20 Mar 03 16:37:20 GMT
Raw View
LLeweLLyn wrote:
 > istream& operator>>(istream& lhs,foo& rhs)
 >   {getline(lhs,rhs.s,'\n');}

You mean
      istream &operator>>(istream &lhs, foo &rhs)
      { return getline(lhs, rhs.s); }

      [Note that the issue here is the missing `return' statement,
      not the presence or absence of the third argument to getline().
       -moderator of comp.std.c++.]

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]




Author: musiphil@bawi.org (KIM Seungbeom)
Date: 18 Mar 03 23:16:37 GMT
Raw View
jpotter@falcon.lhup.edu (John Potter) wrote in message news:<5t83p6$9qr$1@pigpen.csrlink.net>...
> "Bennett Smith" <BennettSmith@acm.org> wrote:
>
> : I'm new to using the Standard C++ Library and am having some trouble with
> : it.  I want to read in a text file and store the contents in a list<string>
> : where each line of the file is in a string.  I cannot figure out an easy
> : way to do this.  Could someone give me some pointers?
>
> #include <iostream>
> #include <fstream>
> #include <string>
> #include <list>
> int main (int argc, char* argv[]) {  // errors ignored for simplicity
>  ifstream f(argv[1]);
>  list<string> l;
>  string s;
>  while (getline(f, s))
>   l.push_back(s);
>  doSomethingWith(l);
>  }
>
> That seems easy enough to me.
>
> Since this is comp.std.c++, I might be missing something in the
> question.  Is there a way to use a standard library algorithm to
> replace s and the following two lines without defining some new class?
> Is there (should there be) an istream_line_iterator?  That would allow
> use of copy.  Some other subtlety that I missed?

This message is quite old, but I'd like to ask again:
Is there a way to use a standard library algorithm to replace
this explicit loop with std::copy?

 string s;
 while (getline(f, s)) l.push_back(s);

Or is there an already-worked-out solution for this?

--
KIM Seungbeom <musiphil@bawi.org>

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]




Author: LLeweLLyn <llewelly.at@xmission.dot.com>
Date: 19 Mar 2003 04:08:01 -0500
Raw View
musiphil@bawi.org (KIM Seungbeom) writes:

> jpotter@falcon.lhup.edu (John Potter) wrote in message news:<5t83p6$9qr$1@pigpen.csrlink.net>...
> > "Bennett Smith" <BennettSmith@acm.org> wrote:
> >
> > : I'm new to using the Standard C++ Library and am having some trouble with
> > : it.  I want to read in a text file and store the contents in a list<string>
> > : where each line of the file is in a string.  I cannot figure out an easy
> > : way to do this.  Could someone give me some pointers?
> >
> > #include <iostream>
> > #include <fstream>
> > #include <string>
> > #include <list>
> > int main (int argc, char* argv[]) {  // errors ignored for simplicity
> >  ifstream f(argv[1]);
> >  list<string> l;
> >  string s;
> >  while (getline(f, s))
> >   l.push_back(s);
> >  doSomethingWith(l);
> >  }
> >
> > That seems easy enough to me.
> >
> > Since this is comp.std.c++, I might be missing something in the
> > question.  Is there a way to use a standard library algorithm to
> > replace s and the following two lines without defining some new class?
> > Is there (should there be) an istream_line_iterator?  That would allow
> > use of copy.  Some other subtlety that I missed?
>
> This message is quite old, but I'd like to ask again:
> Is there a way to use a standard library algorithm to replace
> this explicit loop with std::copy?
>
>  string s;
>  while (getline(f, s)) l.push_back(s);
>
> Or is there an already-worked-out solution for this?
[snip]

struct foo
{
  operator string()const{return s;}
  string s;
};

istream& operator>>(istream& lhs,foo& rhs)
  {getline(lhs,rhs.s,'\n');}

int main(int argc,char* argv[])
  {
    ifstream f(argv[1]);list<string> l;string s;
    copy(istream_iterator<foo>(f),istream_iterator<foo>(),back_inserter(l));
    copy(l.begin(),l.end(),ostream_iterator<string>(cout,"\n"));
  }

(#includes, usings, and standards conformance left as an exercise
    for the reader. :-)

The auxillary struct and operator>> are longer than the while loop,
    >> and IMO less comprehensible. That is, the above is perhaps a
    'solution' but not an improvement.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: jpotter@falcon.lhup.edu (John Potter)
Date: 1997/08/18
Raw View
"Bennett Smith" <BennettSmith@acm.org> wrote:

: I'm new to using the Standard C++ Library and am having some trouble with
: it.  I want to read in a text file and store the contents in a list<string>
: where each line of the file is in a string.  I cannot figure out an easy
: way to do this.  Could someone give me some pointers?

#include <iostream>
#include <fstream>
#include <string>
#include <list>
int main (int argc, char* argv[]) {  // errors ignored for simplicity
 ifstream f(argv[1]);
 list<string> l;
 string s;
 while (getline(f, s))
  l.push_back(s);
 doSomethingWith(l);
 }

That seems easy enough to me.

Since this is comp.std.c++, I might be missing something in the
question.  Is there a way to use a standard library algorithm to
replace s and the following two lines without defining some new class?
Is there (should there be) an istream_line_iterator?  That would allow
use of copy.  Some other subtlety that I missed?

John
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: ouchida@sirius.com (Wayne B. Ouchida)
Date: 1997/08/18
Raw View
On 17 Aug 97 18:09:35 GMT, "Bennett Smith" <BennettSmith@acm.org>
wrote:

>Greetings
>
>I'm new to using the Standard C++ Library and am having some trouble with
>it.  I want to read in a text file and store the contents in a list<string>
>where each line of the file is in a string.  I cannot figure out an easy
>way to do this.  Could someone give me some pointers?

Here is a simple program that reads in a file into a list<string>.
This program adds lines numbers and outputs the result to the display.
The name of the file is taken from the command line.


#include <string>
#include <list>
#include <iostream>
#include <fstream>
#include <cassert>
#include <sstream>
using namespace std;


class file : public list<string> {
public:
  file(char* filename);
  void write(ostream& out = cout);
};


file::file(char* filename) {
  ifstream in(filename);
  assert(in);
  const int sz = 255;
  char buf[sz];

  while(in.getline(buf, sz))
    push_back(buf);
}


void file::write(ostream& out) {
  for(iterator w = begin();  w != end(); w++)
    out << *w << endl;
}


main(int argc, char* argv[])
{
  file File(argv[1]);  // open and read in file
  const int sz = 255;
  int i = 1;

  file::iterator w = File.begin();
  while(w != File.end()) {
    ostringstream os;
    os << i++;
    *w = os.str() + string(": ") + *w;
    w++;
  }

  // Now send them to cout:

  File.write(cout);

  return 0;
}


I hope this helps,

-- Wayne B. Ouchida
-- http://www.sirius.com/~ouchida
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1997/08/19
Raw View
Bennett Smith writes:

> I want to read in a text file and store the contents in a list<string>
> where each line of the file is in a string.  I cannot figure out an easy
> way to do this.  Could someone give me some pointers?

It would be somethink like this: (untested)

list<string> read_as_list_of_strings(ostream& in) {
  list<string> l;
  for(;;) {
    string s;
    getline(in, s);
    if (!in)
      break;
    l.push_back(s);
  }
  return l;
}

--
Alexandre Oliva
mailto:oliva@dcc.unicamp.br mailto:aoliva@acm.org
Universidade Estadual de Campinas, SP, Brasil
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: "Bennett Smith" <BennettSmith@acm.org>
Date: 1997/08/17
Raw View
Greetings

I'm new to using the Standard C++ Library and am having some trouble with
it.  I want to read in a text file and store the contents in a list<string>
where each line of the file is in a string.  I cannot figure out an easy
way to do this.  Could someone give me some pointers?

Many thanks.

-- Bennett
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]