CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 21
  1. #1
    Join Date
    Jul 2013
    Posts
    161

    eof not working properly?

    so I got two questions with this code, first lets work on the efficacy..making it work, then may be a more efficient implementation can be suggested...

    there is a header _row.h
    Code:
    # pragma once
    struct _row
    {
       int c1;
       int c2;
       int c3;
    };
    and a class build wheel
    Code:
    class MakeWheel
    {
    private : std::string text ;
    public :
        MakeWheel (std::string textfile );
    public:
        std::vector<_row> buildWheel();
    
    };
    buildWheel is fed with a text file which contains 3 separated two digits integer on every line...
    the aim is to load every line into a struct object _row..place them in a vector which can be used else where in the bigger application...

    code of buildWheel()
    Code:
    MakeWheel :: MakeWheel (std::string textfile)
    {text = textfile;}
    
    
    std::vector<_row> MakeWheel :: buildWheel ()
    {
         std::string temp, stemp;
         std::vector<_row> hold;
    
         std::ifstream f(text) ;
      if(f.is_open())
      {
         while ( !f.eof() )
        {
          _row *rowpt = new _row ;
          std::getline(f, temp);
    
          stemp = temp.substr(0, 2);
          rowpt->c1 = std::stoi(stemp, nullptr, 0);
    
          stemp = temp.substr(3,2);
          rowpt->c2 = std::stoi(stemp, nullptr, 0);
    
          stemp = temp.substr(6,2);
          rowpt->c3 = std::stoi(stemp, nullptr, 0);
    
          
          hold.push_back(*rowpt);
          delete rowpt;
    
        }
       f.close ();
      }
      else std::cout<<"could not open file to take in raw values for filtering"<<std::endl;
    
     return hold ;
    
    }
    Ok so everything compiles fine..
    but when I run the code I get an out of range error, running it through the debugger I noticed that the problem was in the while brace and to be precise with the eof..after the last line ..getline continues to read the empty space after the last line which I think is loaded into temp and of course being an empty string I get an error with string.substr ...
    or at least this is what I understood with the debugger...
    so the first solution will be to try to make getline not read in an empty string or better still eof flag should really go up after the last line of digits has been read...which for a strange reason is not happening...

    thanks to all who pass by...

  2. #2
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,721

    Re: eof not working properly?

    Generally, this method is always wrong (since eof() does not become true until after
    an attempt has been made to read past eof):
    Code:
    while ( !f.eof() )
    {
        std::getline(f, temp);
    Normally, the coding would be:

    Code:
    while ( getline(f,temp) )
    {

  3. #3
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: eof not working properly?

    Quote Originally Posted by TheLionKing
    but when I run the code I get an out of range error, running it through the debugger I noticed that the problem was in the while brace and to be precise with the eof..after the last line ..getline continues to read the empty space after the last line which I think is loaded into temp and of course being an empty string I get an error with string.substr ...
    or at least this is what I understood with the debugger...
    You understood correctly: the problem is that the EOF flag is only set when end of file is reached (or there is an error, but that is presumably not the case here). But end of file is only reached when getline attempts to read, and finds that it has reached the end of the file. Therefore, you should use the return value of getline to control the loop instead of using the eof member function:
    Code:
    while (std::getline(f, temp))
    {
        _row *rowpt = new _row ;
    
        stemp = temp.substr(0, 2);
        rowpt->c1 = std::stoi(stemp, nullptr, 0);
    
        stemp = temp.substr(3,2);
        rowpt->c2 = std::stoi(stemp, nullptr, 0);
    
        stemp = temp.substr(6,2);
        rowpt->c3 = std::stoi(stemp, nullptr, 0);
    
        hold.push_back(*rowpt);
        delete rowpt;
    }
    Incidentally, I do not see why you need manual memory management here. It looks like you just need to write:
    Code:
    while (std::getline(f, temp))
    {
        auto row_obj = _row{};
    
        row_obj.c1 = std::stoi(temp.substr(0, 2), nullptr, 0);
        row_obj.c2 = std::stoi(temp.substr(3, 2), nullptr, 0);
        row_obj.c3 = std::stoi(temp.substr(6, 2), nullptr, 0);
    
        hold.push_back(row_obj);
    }
    Or maybe even:
    Code:
    while (std::getline(f, temp))
    {
        hold.push_back({
            std::stoi(temp.substr(0, 2), nullptr, 0),
            std::stoi(temp.substr(3, 2), nullptr, 0),
            std::stoi(temp.substr(6, 2), nullptr, 0),
        });
    }
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  4. #4
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: eof not working properly?

    Or even using emplace_back with stream extraction. Consider
    Code:
    #include <vector>
    #include <iostream>
    #include <fstream>
    #include <string>
    using namespace std;
    
    const string vfn = "vec.txt";
    
    struct _row
    {
    	int c1;
    	int c2;
    	int c3;
    
    	_row(int cc1, int cc2, int cc3) : c1(cc1), c2(cc2), c3(cc3) {}
    };
    
    vector<_row> Wheel;
    
    int main()
    {
    	ifstream ifs(vfn);
    
    	if (!ifs.is_open()) {
    		cout << "Cannot open input file " << vfn << endl;
    		return 1;
    	}
    
    	int v1, v2, v3;
    	char ch;
    
    	while (ifs >> v1 >> ch >> v2 >> ch >> v3)
    		Wheel.emplace_back(v1, v2, v3);
    
    	if (!ifs.eof()) {
    		cout << "error reading file!" << endl;
    		return 2;
    	}
    
    	for (const auto& w : Wheel)
    		cout << w.c1 << " " << w.c2 << " " << w.c3 << endl;
    }
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  5. #5
    Join Date
    Jul 2013
    Posts
    161

    Re: eof not working properly?

    Quote Originally Posted by laserlight View Post
    Incidentally, I do not see why you need manual memory management here. It looks like you just need to write:
    thanks will implement your method

  6. #6
    Join Date
    Jul 2013
    Posts
    161

    Re: eof not working properly?

    thanks to you all who responeded!!!

  7. #7
    Join Date
    Jul 2013
    Posts
    161

    Re: eof not working properly?

    Incidentally, I do not see why you need manual memory management here. It looks like you just need to write:
    hello man, thanks but there is a trick you used here that is new to me..wow this one right here..

    auto row_obj = _row{};
    so what is the technical name of this trick? so just by assigning a variable to a class/struct name with curly braces and ; an object of type of the class/struct is created? nice!
    do we ever stop learning???

  8. #8
    Join Date
    Jul 2013
    Posts
    161

    Re: eof not working properly?

    Master 2kaud can you shed more light on the way you designed the struct please? I mean what about the
    _row(int cc1, int cc2, int cc3) : c1(cc1), c2(cc2), c3(cc3) {}
    inside the struct? what is the technical name of this move too? can you explain more please..thanks..

  9. #9
    Join Date
    Jul 2013
    Posts
    161

    Re: eof not working properly?

    Any way guys, the solution you gave didn't work! but thanks soo much for the different implementations you gave...that was soo useful...
    the solution didn't work because even by using
    while (std::getline(f, temp) ) , getling was still reading in an empty string at the end...so I solved it by adding this other condition...

    whilte(std::getline(f,temp) && temp.size() > 0) ;

  10. #10
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: eof not working properly?

    Quote Originally Posted by TheLionKing
    while (std::getline(f, temp) ) , getling was still reading in an empty string at the end...so I solved it by adding this other condition...
    Oh, if there is indeed a blank line at the end in the input, then of course just checking the return value of getline will not suffice. However, this points to another problem: you rely on std::stoi to validate the input, but you did not catch the possible std::invalid_argument exception. What if it was not a blank line, but nonetheless was invalid input?
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  11. #11
    Join Date
    Jul 2013
    Posts
    161

    Re: eof not working properly?

    ok laserlight, can you please say something about the question I asked you earlier on? about this
    auto row_obj = _row{};

  12. #12
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: eof not working properly?

    Quote Originally Posted by TheLionKing View Post
    Master 2kaud can you shed more light on the way you designed the struct please? I mean what about the
    inside the struct? what is the technical name of this move too? can you explain more please..thanks..
    in c++, struct is just like a class and can have constructors and a destructor. The only difference is that in a struct all is public by default and in a class all is private by default. So that line is just a constructor for _row that takes 3 ints and assigns them to c1, c2 and c3 using a member initializer list. See https://msdn.microsoft.com/en-us/library/s16xw1a8.aspx member lists.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  13. #13
    Join Date
    Jul 2013
    Posts
    161

    Re: eof not working properly?

    Thanks Master 2kaud!

  14. #14
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: eof not working properly?

    Quote Originally Posted by TheLionKing View Post
    Any way guys, the solution you gave didn't work! but thanks soo much for the different implementations you gave...that was soo useful...
    the solution didn't work because even by using
    while (std::getline(f, temp) ) , getling was still reading in an empty string at the end...so I solved it by adding this other condition...

    whilte(std::getline(f,temp) && temp.size() > 0) ;
    Note that the code in my post #4 ignores blank lines so having an empty line at the end (or even multiple blank lines during the file) doesn't effect it's operation.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  15. #15
    Join Date
    Jul 2013
    Posts
    161

    Re: eof not working properly?

    I admit I didn't implement your solution master 2kaud, will look into that..thanks for re bringing it to my attention

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured