File reading problem

Discussion in 'C++' started by Eric Lilja, Jul 15, 2007.

  1. Eric Lilja

    Eric Lilja Guest

    Hi! I have a program with a class that needs to be able to write
    itself to a file in clear text format. The file has two integers and
    vector of struct objects. The struct has a string that can consist of
    one or more words and a few integers. I'm able to create the file
    properly, as confimed by viewing it in a text editor, but something
    goes wrong when I tried to read it. I've made a test program
    illustrating the problem:

    #include <fstream>
    #include <iostream>
    #include <string>
    #include <vector>

    using namespace std;

    struct s_t
    {
    s_t() {}
    s_t(const string& si, int xi, int yi) : s(si), x(xi), y(yi) {}
    string s;
    int x, y;

    friend ostream& operator<<(ostream& os, const s_t& rhs);
    friend istream& operator>>(istream& is, s_t& rhs);
    };

    ostream&
    operator<<(ostream& os, const s_t& rhs)
    {
    os << rhs.s << endl;
    os << rhs.x << ' ' << rhs.y;

    return os;
    }

    istream&
    operator>>(istream& is, s_t& rhs)
    {
    getline(is, rhs.s);

    is >> rhs.x >> rhs.y;

    return is;
    }

    void
    readit()
    {
    int x = 0, y = 0;
    vector<s_t> vec;

    ifstream in("foo.txt");

    in >> x >> y;

    {
    s_t temp;

    while (in >> temp) vec.push_back(temp);
    }

    in.close();

    cout << x << ' ' << y << endl;
    cout << vec.size() << endl;
    for (unsigned int i = 0; i < vec.size(); i++)
    cout << vec.at(i) << endl;
    }

    int
    main()
    {
    int x = 4711, y = 1337;
    vector<s_t> vec;

    vec.push_back(s_t("foo bar", 33, 22));
    vec.push_back(s_t("bar baz", 11, 99));

    ofstream out("foo.txt");

    out << x << ' ' << y << endl;
    for (unsigned int i = 0; i < vec.size(); i++)
    {
    out << vec.at(i);

    if (i < vec.size() - 1)
    out << endl;
    }

    out.flush();
    out.close();

    readit();
    }

    When I run it, I get this output:
    4711 1337
    0

    so it reads the first two numbers ok but reading the s_t objects
    doesn't work because the vector is empty afterwards...

    Any help appreciated.

    - E
    Eric Lilja, Jul 15, 2007
    #1
    1. Advertising

  2. Eric Lilja wrote:

    > Hi! I have a program with a class that needs to be able to write
    > itself to a file in clear text format. The file has two integers and
    > vector of struct objects. The struct has a string that can consist of
    > one or more words and a few integers. I'm able to create the file
    > properly, as confimed by viewing it in a text editor, but something
    > goes wrong when I tried to read it. I've made a test program
    > illustrating the problem:
    >
    > #include <fstream>
    > #include <iostream>
    > #include <string>
    > #include <vector>
    >
    > using namespace std;
    >
    > struct s_t
    > {
    > s_t() {}
    > s_t(const string& si, int xi, int yi) : s(si), x(xi), y(yi) {}
    > string s;
    > int x, y;
    >
    > friend ostream& operator<<(ostream& os, const s_t& rhs);
    > friend istream& operator>>(istream& is, s_t& rhs);
    > };
    >
    > ostream&
    > operator<<(ostream& os, const s_t& rhs)
    > {
    > os << rhs.s << endl;
    > os << rhs.x << ' ' << rhs.y;
    >
    > return os;
    > }
    >
    > istream&
    > operator>>(istream& is, s_t& rhs)
    > {
    > getline(is, rhs.s);
    >
    > is >> rhs.x >> rhs.y;
    >
    > return is;
    > }
    >
    > void
    > readit()
    > {
    > int x = 0, y = 0;
    > vector<s_t> vec;
    >
    > ifstream in("foo.txt");
    >
    > in >> x >> y;


    After this, the next character in the input stream should be a '\n'.

    >
    > {
    > s_t temp;
    >


    This will now read to the first newline in the stream and put the result
    into temp.s. Since the first character is a newline, temp.s will be empty.
    Then in will try to put the contents of what's stored as a string into
    temp.x. In this case, in finds 'f', and fails. Thus the reading of the two
    ints will become a noop, and the test fails.

    I suggest you look up the ignore() member function of istream. You need to
    ignore the rest of the line.

    > while (in >> temp) vec.push_back(temp);
    > }
    >
    > in.close();
    >
    > cout << x << ' ' << y << endl;
    > cout << vec.size() << endl;
    > for (unsigned int i = 0; i < vec.size(); i++)
    > cout << vec.at(i) << endl;
    > }
    >
    > int
    > main()
    > {
    > int x = 4711, y = 1337;
    > vector<s_t> vec;
    >
    > vec.push_back(s_t("foo bar", 33, 22));
    > vec.push_back(s_t("bar baz", 11, 99));
    >
    > ofstream out("foo.txt");
    >
    > out << x << ' ' << y << endl;
    > for (unsigned int i = 0; i < vec.size(); i++)
    > {
    > out << vec.at(i);
    >
    > if (i < vec.size() - 1)
    > out << endl;
    > }
    >
    > out.flush();
    > out.close();
    >
    > readit();
    > }
    >
    > When I run it, I get this output:
    > 4711 1337
    > 0
    >
    > so it reads the first two numbers ok but reading the s_t objects
    > doesn't work because the vector is empty afterwards...
    >
    > Any help appreciated.


    It's a common beginner error. Try to hand trace the code. Write down the
    contents of the file on paper with control characters, and see where the
    next char to be read is.

    --
    rbh
    Robert Bauck Hamar, Jul 15, 2007
    #2
    1. Advertising

  3. Eric Lilja

    Eric Lilja Guest

    On 15 Juli, 15:12, Robert Bauck Hamar <> wrote:
    > Eric Lilja wrote:
    > > Hi! I have a program with a class that needs to be able to write
    > > itself to a file in clear text format. The file has two integers and
    > > vector of struct objects. The struct has a string that can consist of
    > > one or more words and a few integers. I'm able to create the file
    > > properly, as confimed by viewing it in a text editor, but something
    > > goes wrong when I tried to read it. I've made a test program
    > > illustrating the problem:

    >
    > > #include <fstream>
    > > #include <iostream>
    > > #include <string>
    > > #include <vector>

    >
    > > using namespace std;

    >
    > > struct s_t
    > > {
    > > s_t() {}
    > > s_t(const string& si, int xi, int yi) : s(si), x(xi), y(yi) {}
    > > string s;
    > > int x, y;

    >
    > > friend ostream& operator<<(ostream& os, const s_t& rhs);
    > > friend istream& operator>>(istream& is, s_t& rhs);
    > > };

    >
    > > ostream&
    > > operator<<(ostream& os, const s_t& rhs)
    > > {
    > > os << rhs.s << endl;
    > > os << rhs.x << ' ' << rhs.y;

    >
    > > return os;
    > > }

    >
    > > istream&
    > > operator>>(istream& is, s_t& rhs)
    > > {
    > > getline(is, rhs.s);

    >
    > > is >> rhs.x >> rhs.y;

    >
    > > return is;
    > > }

    >
    > > void
    > > readit()
    > > {
    > > int x = 0, y = 0;
    > > vector<s_t> vec;

    >
    > > ifstream in("foo.txt");

    >
    > > in >> x >> y;

    >
    > After this, the next character in the input stream should be a '\n'.
    >
    >
    >
    > > {
    > > s_t temp;

    >
    > This will now read to the first newline in the stream and put the result
    > into temp.s. Since the first character is a newline, temp.s will be empty.
    > Then in will try to put the contents of what's stored as a string into
    > temp.x. In this case, in finds 'f', and fails. Thus the reading of the two
    > ints will become a noop, and the test fails.
    >
    > I suggest you look up the ignore() member function of istream. You need to
    > ignore the rest of the line.


    I solved it by adding this to my overloaded operator>>:
    if (is.peek() == '\n')
    {
    is.ignore();
    }
    before the getline() call. Now that program works just fine. However,
    the *real* program tries to read even though there are no more entries
    in the file. Hmm.

    >
    >
    >
    > > while (in >> temp) vec.push_back(temp);
    > > }

    >
    > > in.close();

    >
    > > cout << x << ' ' << y << endl;
    > > cout << vec.size() << endl;
    > > for (unsigned int i = 0; i < vec.size(); i++)
    > > cout << vec.at(i) << endl;
    > > }

    >
    > > int
    > > main()
    > > {
    > > int x = 4711, y = 1337;
    > > vector<s_t> vec;

    >
    > > vec.push_back(s_t("foo bar", 33, 22));
    > > vec.push_back(s_t("bar baz", 11, 99));

    >
    > > ofstream out("foo.txt");

    >
    > > out << x << ' ' << y << endl;
    > > for (unsigned int i = 0; i < vec.size(); i++)
    > > {
    > > out << vec.at(i);

    >
    > > if (i < vec.size() - 1)
    > > out << endl;
    > > }

    >
    > > out.flush();
    > > out.close();

    >
    > > readit();
    > > }

    >
    > > When I run it, I get this output:
    > > 4711 1337
    > > 0

    >
    > > so it reads the first two numbers ok but reading the s_t objects
    > > doesn't work because the vector is empty afterwards...

    >
    > > Any help appreciated.

    >
    > It's a common beginner error. Try to hand trace the code. Write down the
    > contents of the file on paper with control characters, and see where the
    > next char to be read is.
    >
    > --
    > rbh
    Eric Lilja, Jul 15, 2007
    #3
  4. Eric Lilja

    Eric Lilja Guest

    On 15 Juli, 16:18, Eric Lilja <> wrote:
    > On 15 Juli, 15:12, Robert Bauck Hamar <> wrote:
    >
    >
    >
    > > Eric Lilja wrote:
    > > > Hi! I have a program with a class that needs to be able to write
    > > > itself to a file in clear text format. The file has two integers and
    > > > vector of struct objects. The struct has a string that can consist of
    > > > one or more words and a few integers. I'm able to create the file
    > > > properly, as confimed by viewing it in a text editor, but something
    > > > goes wrong when I tried to read it. I've made a test program
    > > > illustrating the problem:

    >
    > > > #include <fstream>
    > > > #include <iostream>
    > > > #include <string>
    > > > #include <vector>

    >
    > > > using namespace std;

    >
    > > > struct s_t
    > > > {
    > > > s_t() {}
    > > > s_t(const string& si, int xi, int yi) : s(si), x(xi), y(yi) {}
    > > > string s;
    > > > int x, y;

    >
    > > > friend ostream& operator<<(ostream& os, const s_t& rhs);
    > > > friend istream& operator>>(istream& is, s_t& rhs);
    > > > };

    >
    > > > ostream&
    > > > operator<<(ostream& os, const s_t& rhs)
    > > > {
    > > > os << rhs.s << endl;
    > > > os << rhs.x << ' ' << rhs.y;

    >
    > > > return os;
    > > > }

    >
    > > > istream&
    > > > operator>>(istream& is, s_t& rhs)
    > > > {
    > > > getline(is, rhs.s);

    >
    > > > is >> rhs.x >> rhs.y;

    >
    > > > return is;
    > > > }

    >
    > > > void
    > > > readit()
    > > > {
    > > > int x = 0, y = 0;
    > > > vector<s_t> vec;

    >
    > > > ifstream in("foo.txt");

    >
    > > > in >> x >> y;

    >
    > > After this, the next character in the input stream should be a '\n'.

    >
    > > > {
    > > > s_t temp;

    >
    > > This will now read to the first newline in the stream and put the result
    > > into temp.s. Since the first character is a newline, temp.s will be empty.
    > > Then in will try to put the contents of what's stored as a string into
    > > temp.x. In this case, in finds 'f', and fails. Thus the reading of the two
    > > ints will become a noop, and the test fails.

    >
    > > I suggest you look up the ignore() member function of istream. You need to
    > > ignore the rest of the line.

    >
    > I solved it by adding this to my overloaded operator>>:
    > if (is.peek() == '\n')
    > {
    > is.ignore();}
    >
    > before the getline() call. Now that program works just fine. However,
    > the *real* program tries to read even though there are no more entries
    > in the file. Hmm.


    And I solved that by checking the return value of the getline() call
    and returning
    the stream directly if it fails.

    >
    >
    >
    > > > while (in >> temp) vec.push_back(temp);
    > > > }

    >
    > > > in.close();

    >
    > > > cout << x << ' ' << y << endl;
    > > > cout << vec.size() << endl;
    > > > for (unsigned int i = 0; i < vec.size(); i++)
    > > > cout << vec.at(i) << endl;
    > > > }

    >
    > > > int
    > > > main()
    > > > {
    > > > int x = 4711, y = 1337;
    > > > vector<s_t> vec;

    >
    > > > vec.push_back(s_t("foo bar", 33, 22));
    > > > vec.push_back(s_t("bar baz", 11, 99));

    >
    > > > ofstream out("foo.txt");

    >
    > > > out << x << ' ' << y << endl;
    > > > for (unsigned int i = 0; i < vec.size(); i++)
    > > > {
    > > > out << vec.at(i);

    >
    > > > if (i < vec.size() - 1)
    > > > out << endl;
    > > > }

    >
    > > > out.flush();
    > > > out.close();

    >
    > > > readit();
    > > > }

    >
    > > > When I run it, I get this output:
    > > > 4711 1337
    > > > 0

    >
    > > > so it reads the first two numbers ok but reading the s_t objects
    > > > doesn't work because the vector is empty afterwards...

    >
    > > > Any help appreciated.

    >
    > > It's a common beginner error. Try to hand trace the code. Write down the
    > > contents of the file on paper with control characters, and see where the
    > > next char to be read is.

    >
    > > --
    > > rbh
    Eric Lilja, Jul 15, 2007
    #4
  5. Eric Lilja

    BobR Guest

    Eric Lilja <> wrote in message...
    > On 15 Juli, 16:18, Eric Lilja <> wrote:
    > > On 15 Juli, 15:12, Robert Bauck Hamar <> wrote:
    > >
    > > > > #include <fstream>
    > > > > #include <iostream>
    > > > > #include <string>
    > > > > #include <vector>
    > > > > using namespace std;

    > >
    > > > > struct s_t{
    > > > > s_t() {}
    > > > > s_t(const string& si, int xi, int yi) : s(si), x(xi), y(yi) {}
    > > > > string s;
    > > > > int x, y;
    > > > > friend ostream& operator<<(ostream& os, const s_t& rhs);
    > > > > friend istream& operator>>(istream& is, s_t& rhs);
    > > > > };

    > >
    > > > > ostream& operator<<(ostream& os, const s_t& rhs){
    > > > > os << rhs.s << endl;
    > > > > os << rhs.x << ' ' << rhs.y;
    > > > > return os;
    > > > > }

    > >
    > > > > istream& operator>>(istream& is, s_t& rhs){
    > > > > getline(is, rhs.s);
    > > > > is >> rhs.x >> rhs.y;
    > > > > return is;
    > > > > }

    > >
    > > > > void readit(){
    > > > > int x = 0, y = 0;
    > > > > vector<s_t> vec;
    > > > > ifstream in("foo.txt");
    > > > > in >> x >> y;

    > >
    > > > After this, the next character in the input stream should be a '\n'.

    > >
    > > > > {
    > > > > s_t temp;

    > >
    > > > This will now read to the first newline in the stream and put the

    result
    > > > into temp.s. Since the first character is a newline, temp.s will be

    empty.
    > > > Then in will try to put the contents of what's stored as a string into
    > > > temp.x. In this case, in finds 'f', and fails. Thus the reading of the

    two
    > > > ints will become a noop, and the test fails.

    > >
    > > > I suggest you look up the ignore() member function of istream. You

    need to
    > > > ignore the rest of the line.

    > >
    > > I solved it by adding this to my overloaded operator>>:
    > > if (is.peek() == '\n'){ is.ignore();}
    > >
    > > before the getline() call. Now that program works just fine. However,
    > > the *real* program tries to read even though there are no more entries
    > > in the file. Hmm.

    >
    > And I solved that by checking the return value of the getline() call
    > and returning the stream directly if it fails.
    > >
    > > > > while (in >> temp) vec.push_back(temp);
    > > > > }
    > > > > in.close();
    > > > > cout << x << ' ' << y << endl;
    > > > > cout << vec.size() << endl;
    > > > > for (unsigned int i = 0; i < vec.size(); i++)
    > > > > cout << vec.at(i) << endl;
    > > > > }

    > >
    > > > > int main(){
    > > > > int x = 4711, y = 1337;
    > > > > vector<s_t> vec;
    > > > > vec.push_back(s_t("foo bar", 33, 22));
    > > > > vec.push_back(s_t("bar baz", 11, 99));
    > > > > ofstream out("foo.txt");
    > > > > out << x << ' ' << y << endl;
    > > > > for (unsigned int i = 0; i < vec.size(); i++){
    > > > > out << vec.at(i);
    > > > > if (i < vec.size() - 1)
    > > > > out << endl;
    > > > > }
    > > > > out.flush();
    > > > > out.close();
    > > > > readit();
    > > > > }

    > >

    >


    Your 'vector' in 'main()' is separate from the 'vector' in 'readit()'. If
    you want to fill a 'vector' from 'main()', try adding this (no need to
    remove your current version):

    void readit( std::vector<s_t> &vec ){ // non-const
    ifstream in("foo.txt");
    if( not in.is_open() ){ std::cerr<<"ERROR"; return; }
    int x( 0 ), y( 0 );
    in >> x >> y;
    if( in.peek() == '\n' ){ in.ignore(); }
    s_t temp;
    while( in >> temp ) vec.push_back( temp );
    // untested. replace the above two lines with:
    // for( s_t temp; in >> temp; /*m_t*/ ){
    // vec.push_back( temp );
    // } // for(in)
    } // readit( std::vector<s_t>&)

    { // main
    // .....
    std::vector<s_t> vst;
    readit( vst );
    for( std::size_t i(0); i < vst.size(); ++i )
    cout << vst.at(i) << endl;
    }

    --
    Bob R
    POVrookie
    BobR, Jul 15, 2007
    #5
  6. Eric Lilja

    Eric Lilja Guest

    On 15 Juli, 20:12, "BobR" <> wrote:
    > Eric Lilja <> wrote in message...
    > > On 15 Juli, 16:18, Eric Lilja <> wrote:
    > > > On 15 Juli, 15:12, Robert Bauck Hamar <> wrote:

    >
    > > > > > #include <fstream>
    > > > > > #include <iostream>
    > > > > > #include <string>
    > > > > > #include <vector>
    > > > > > using namespace std;

    >
    > > > > > struct s_t{
    > > > > > s_t() {}
    > > > > > s_t(const string& si, int xi, int yi) : s(si), x(xi), y(yi) {}
    > > > > > string s;
    > > > > > int x, y;
    > > > > > friend ostream& operator<<(ostream& os, const s_t& rhs);
    > > > > > friend istream& operator>>(istream& is, s_t& rhs);
    > > > > > };

    >
    > > > > > ostream& operator<<(ostream& os, const s_t& rhs){
    > > > > > os << rhs.s << endl;
    > > > > > os << rhs.x << ' ' << rhs.y;
    > > > > > return os;
    > > > > > }

    >
    > > > > > istream& operator>>(istream& is, s_t& rhs){
    > > > > > getline(is, rhs.s);
    > > > > > is >> rhs.x >> rhs.y;
    > > > > > return is;
    > > > > > }

    >
    > > > > > void readit(){
    > > > > > int x = 0, y = 0;
    > > > > > vector<s_t> vec;
    > > > > > ifstream in("foo.txt");
    > > > > > in >> x >> y;

    >
    > > > > After this, the next character in the input stream should be a '\n'.

    >
    > > > > > {
    > > > > > s_t temp;

    >
    > > > > This will now read to the first newline in the stream and put the

    > result
    > > > > into temp.s. Since the first character is a newline, temp.s will be

    > empty.
    > > > > Then in will try to put the contents of what's stored as a string into
    > > > > temp.x. In this case, in finds 'f', and fails. Thus the reading of the

    > two
    > > > > ints will become a noop, and the test fails.

    >
    > > > > I suggest you look up the ignore() member function of istream. You

    > need to
    > > > > ignore the rest of the line.

    >
    > > > I solved it by adding this to my overloaded operator>>:
    > > > if (is.peek() == '\n'){ is.ignore();}

    >
    > > > before the getline() call. Now that program works just fine. However,
    > > > the *real* program tries to read even though there are no more entries
    > > > in the file. Hmm.

    >
    > > And I solved that by checking the return value of the getline() call
    > > and returning the stream directly if it fails.

    >
    > > > > > while (in >> temp) vec.push_back(temp);
    > > > > > }
    > > > > > in.close();
    > > > > > cout << x << ' ' << y << endl;
    > > > > > cout << vec.size() << endl;
    > > > > > for (unsigned int i = 0; i < vec.size(); i++)
    > > > > > cout << vec.at(i) << endl;
    > > > > > }

    >
    > > > > > int main(){
    > > > > > int x = 4711, y = 1337;
    > > > > > vector<s_t> vec;
    > > > > > vec.push_back(s_t("foo bar", 33, 22));
    > > > > > vec.push_back(s_t("bar baz", 11, 99));
    > > > > > ofstream out("foo.txt");
    > > > > > out << x << ' ' << y << endl;
    > > > > > for (unsigned int i = 0; i < vec.size(); i++){
    > > > > > out << vec.at(i);
    > > > > > if (i < vec.size() - 1)
    > > > > > out << endl;
    > > > > > }
    > > > > > out.flush();
    > > > > > out.close();
    > > > > > readit();
    > > > > > }

    >
    > Your 'vector' in 'main()' is separate from the 'vector' in 'readit()'. If
    > you want to fill a 'vector' from 'main()', try adding this (no need to
    > remove your current version):
    >
    > void readit( std::vector<s_t> &vec ){ // non-const
    > ifstream in("foo.txt");
    > if( not in.is_open() ){ std::cerr<<"ERROR"; return; }
    > int x( 0 ), y( 0 );
    > in >> x >> y;
    > if( in.peek() == '\n' ){ in.ignore(); }
    > s_t temp;
    > while( in >> temp ) vec.push_back( temp );
    > // untested. replace the above two lines with:
    > // for( s_t temp; in >> temp; /*m_t*/ ){
    > // vec.push_back( temp );
    > // } // for(in)
    > } // readit( std::vector<s_t>&)
    >
    > { // main
    > // .....
    > std::vector<s_t> vst;
    > readit( vst );
    > for( std::size_t i(0); i < vst.size(); ++i )
    > cout << vst.at(i) << endl;
    >
    > }



    Umm, yeah, I know, this was just a program for illustrating a file
    reading problem. I don't care in this program if I use different
    vectors, it's completely irrelevant. And I know perfectly well what
    passing a variable by reference means...

    >
    > --
    > Bob R
    > POVrookie
    Eric Lilja, Jul 15, 2007
    #6
  7. Eric Lilja

    James Kanze Guest

    On Jul 15, 8:12 pm, "BobR" <> wrote:

    [...]
    > void readit( std::vector<s_t> &vec ){ // non-const
    > ifstream in("foo.txt");
    > if( not in.is_open() ){ std::cerr<<"ERROR"; return; }
    > int x( 0 ), y( 0 );
    > in >> x >> y;


    You probably want to check the return values here. But I'm not
    too sure what this function is designed to do, to begin with.

    > if( in.peek() == '\n' ){ in.ignore(); }


    What's the purpose of this line? The following "in >> temp"
    will automatically skip any leading white space (and '\n' is
    white space).

    If the input is line oriented, and you want to verify its
    format, then you should probably read using getline, then use
    istringstream to parse it (not forgetting a final
    if ( line >> std::ws && line.get() == EOF ) ...
    to ensure that there's no trailing garbage). If it's just a
    collection of white space separated s_t, then you can just read,
    you don't need to "ignore" anything.

    > s_t temp;
    > while( in >> temp ) vec.push_back( temp );
    > // untested. replace the above two lines with:
    > // for( s_t temp; in >> temp; /*m_t*/ ){


    Doesn't work. The first pass through the loop will use an
    uninitialized temp.

    > // vec.push_back( temp );
    > // } // for(in)
    > } // readit( std::vector<s_t>&)


    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jul 16, 2007
    #7
  8. Eric Lilja

    Eric Lilja Guest

    On 16 Juli, 09:38, James Kanze <> wrote:
    > On Jul 15, 8:12 pm, "BobR" <> wrote:
    >
    > [...]
    >
    > > void readit( std::vector<s_t> &vec ){ // non-const
    > > ifstream in("foo.txt");
    > > if( not in.is_open() ){ std::cerr<<"ERROR"; return; }
    > > int x( 0 ), y( 0 );
    > > in >> x >> y;

    >
    > You probably want to check the return values here. But I'm not
    > too sure what this function is designed to do, to begin with.
    >
    > > if( in.peek() == '\n' ){ in.ignore(); }

    >
    > What's the purpose of this line? The following "in >> temp"
    > will automatically skip any leading white space (and '\n' is
    > white space).
    >
    > If the input is line oriented, and you want to verify its
    > format, then you should probably read using getline, then use
    > istringstream to parse it (not forgetting a final
    > if ( line >> std::ws && line.get() == EOF ) ...
    > to ensure that there's no trailing garbage). If it's just a
    > collection of white space separated s_t, then you can just read,
    > you don't need to "ignore" anything.
    >
    > > s_t temp;
    > > while( in >> temp ) vec.push_back( temp );
    > > // untested. replace the above two lines with:
    > > // for( s_t temp; in >> temp; /*m_t*/ ){

    >
    > Doesn't work. The first pass through the loop will use an
    > uninitialized temp.


    Huh?

    and btw, the program works just fine now so I don't see the reason for
    this post anyway...

    >
    > > // vec.push_back( temp );
    > > // } // for(in)
    > > } // readit( std::vector<s_t>&)

    >
    > --
    > James Kanze (GABI Software) email:
    > Conseils en informatique orientée objet/
    > Beratung in objektorientierter Datenverarbeitung
    > 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    Eric Lilja, Jul 16, 2007
    #8
  9. James Kanze wrote:

    > On Jul 15, 8:12 pm, "BobR" <> wrote:
    >
    > [...]
    >> void readit( std::vector<s_t> &vec ){ // non-const
    >> ifstream in("foo.txt");
    >> if( not in.is_open() ){ std::cerr<<"ERROR"; return; }
    >> int x( 0 ), y( 0 );
    >> in >> x >> y;

    >
    > You probably want to check the return values here. But I'm not
    > too sure what this function is designed to do, to begin with.
    >
    >> if( in.peek() == '\n' ){ in.ignore(); }

    >
    > What's the purpose of this line? The following "in >> temp"
    > will automatically skip any leading white space (and '\n' is
    > white space).


    No, it will not. in >> temp calls the user defined operator>>(istream& i,
    s_t& st), which in turn commence by calling getline(i, st). Without the
    in.ignore(), or using some other means of skipping the newline, this will
    not work correctly.

    --
    rbh
    Robert Bauck Hamar, Jul 16, 2007
    #9
  10. Eric Lilja

    Eric Lilja Guest

    On 16 Juli, 13:54, Robert Bauck Hamar <> wrote:
    > James Kanze wrote:
    > > On Jul 15, 8:12 pm, "BobR" <> wrote:

    >
    > > [...]
    > >> void readit( std::vector<s_t> &vec ){ // non-const
    > >> ifstream in("foo.txt");
    > >> if( not in.is_open() ){ std::cerr<<"ERROR"; return; }
    > >> int x( 0 ), y( 0 );
    > >> in >> x >> y;

    >
    > > You probably want to check the return values here. But I'm not
    > > too sure what this function is designed to do, to begin with.

    >
    > >> if( in.peek() == '\n' ){ in.ignore(); }

    >
    > > What's the purpose of this line? The following "in >> temp"
    > > will automatically skip any leading white space (and '\n' is
    > > white space).

    >
    > No, it will not. in >> temp calls the user defined operator>>(istream& i,
    > s_t& st), which in turn commence by calling getline(i, st). Without the
    > in.ignore(), or using some other means of skipping the newline, this will
    > not work correctly.
    >
    > --
    > rbh


    But the code has an ignore (did you read the entire thread?). The
    reading works (tested with two different compilers) now and I'm
    working on other bugs and features now.
    Eric Lilja, Jul 16, 2007
    #10
    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. Darrel
    Replies:
    3
    Views:
    670
    Kevin Spencer
    Nov 11, 2004
  2. Wael Soliman

    ASP.NET Reading problem (reading .xls)

    Wael Soliman, Jan 3, 2005, in forum: ASP .Net
    Replies:
    2
    Views:
    4,789
    =?Utf-8?B?dmluYXk=?=
    Jan 3, 2005
  3. Luis Esteban Valencia Muñoz
    Replies:
    3
    Views:
    1,405
    Scott Allen
    Jun 4, 2005
  4. Replies:
    0
    Views:
    780
  5. Karim Ali

    Reading a file and resuming reading.

    Karim Ali, May 25, 2007, in forum: Python
    Replies:
    2
    Views:
    370
    Hrvoje Niksic
    May 25, 2007
Loading...

Share This Page