Thread: Prevent the loop from reading the last file line twice

  1. #1
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694

    Prevent the loop from reading the last file line twice

    I know how to do it in C, but in C++?

    Here is my code. Let the variables be of type double.
    Code:
    while(infile) // Will read the last line twice
        {
        	if(!N)	//Read first line of file
        	{
        		infile >> d;
        		infile >> N;
        		infile >> epsilon;
        		infile >> t;
        	}
        	else
        	{
        		double hCoords[P.getD()];
        		for(size_t i = 0 ; i < P.getD() ; ++i)
        			infile >> hCoords[i];
    
        		//Read min distance of origin
        		infile >> d;
        	}
        }
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  2. #2
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    You can read into a temporary variable first, then test for eof.

    If eof is set (meaning last read value is invalid), just break out of the loop, otherwise continue.

  3. #3
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    actually you should check result of each read to be sure it was successful instead of checking the stream state postfactum

    Code:
    while(infile) // Will read the last line twice
        {
            if(!N)  //Read first line of file
            {
                if(infile >> d >> N >> epsilon >> t)
                {
                  //first line read OK
                }
                else
                {
                  //error occurred - notify and exit
                }
            }
    ...
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  4. #4
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    Vart I am not looking for an error, but for the EOF.

    Cyberfish, with this code
    Code:
    while(infile) // Will read the last line twice
        {
        	if(!N)	//Read first line of file
        	{
        		infile >> d;
        		P.setD(d);
        		infile >> N;
        		infile >> epsilon;
        		infile >> t;
        	}
        	else
        	{
        		double hCoords[P.getD()];
        		for(size_t i = 0 ; i < P.getD() ; ++i)
        		{
        			infile >> d;
        			//std::cout << d << " " << i << std::endl;
        			//if(d==EOF)break;
        			hCoords[i] = d;
        			std::cout <<hCoords[i]  << "\n";
        		}
    
        		//Read min distance of origin
        		infile >> d;
        		std::cout << hCoords[0] << " " << hCoords[1] << " "
        				<< hCoords[2] << " " << d << "\n";
        	}
        }
    I read as expected and I read the line twice, which is
    Code:
    -0
    -0
    -1
    -0 -0 -1 -0
    0
    -1
    0
    0 -1 0 0
    -1
    -0
    -0
    -1 -0 -0 -0
    0.57735
    0.57735
    0.57735
    0.57735 0.57735 0.57735 0.57735
    0.57735
    0.57735
    0.57735
    0.57735 0.57735 0.57735 0.57735
    Here is my file.
    Code:
    3 4 0.1 3
    -0.000000000 -0.000000000 -1.000000000 -0.000000000
     0.000000000 -1.000000000  0.000000000  0.000000000
    -1.000000000 -0.000000000 -0.000000000 -0.000000000
     0.577350269  0.577350269  0.577350269  0.577350269
    If I uncomment the two lines of code, I am getting this
    Code:
    -0
    -0
    -0 -0 -1.71101e-41 -0
    0
    0 -0 -1.71101e-41 0
    0
    0 -0 -1.71101e-41 -0
    -0
    -0
    0.57735
    -0 -0 0.57735 0.57735
    0.57735
    0.57735
    0.57735
    0.57735 0.57735 0.57735 0.57735
    Moreover, I tried infile.eof(), but with no use at all.
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You seem to know that infile can return false when the previous read failed, as that's the point behind "while (infile)" in the first place. But it's not prescient -- it doesn't know that the next call is going to fail, it can only tell you that the previous call failed. If you've already (tried to) process that previous read then it's too late. Check the state of infile before you do anything.

  6. #6
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    You actually have to "hit" the end-of-file for it to be detected. If you have the filesize info elsewhere, you can use that to control the loop. I don't know what your data is, but perhaps N is the number of records in the file? If so, you could write:
    Code:
    //Read first line of file
    infile >> d;
    P.setD(d);
    infile >> N;
    infile >> epsilon;
    infile >> t;
    
    for (size_t n = 0; n < N && infile; n++)
    {
        double hCoords[P.getD()];
        for (size_t i = 0; i < P.getD(); ++i)
            infile >> hCoords[i];
    
        // Read min distance of origin
        infile >> d;
    
        // Display data
        for (size_t i = 0; i < P.getD(); ++i)
            std::cout << hCoords[i] << ' ';
        std::cout << d << '\n';
    }
    BTW, your variable names ain't too great.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  7. #7
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by std10093 View Post
    Vart I am not looking for an error, but for the EOF.
    And what you will do in case of error?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  8. #8
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    That did the trick.
    I explain the variables when I declare them, but ok, I see your point.

    vart, I do the check when I open the file. If the file has opened ok, then I procede with parsing it.
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  9. #9
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by std10093 View Post
    vart, I do the check when I open the file. If the file has opened ok, then I procede with parsing it.
    You mean your file reading never fails? File could never be corrupted or overwritten by too smart user? or by mistake with some garbage? You are to optimistic in your programming style for my taste.
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to prevent fgets from reading the new line character
    By Nyah Check in forum C Programming
    Replies: 2
    Last Post: 03-12-2013, 01:59 PM
  2. Replies: 6
    Last Post: 06-07-2012, 02:50 AM
  3. Replies: 7
    Last Post: 12-13-2010, 02:13 PM
  4. Reading Input from a file, line-by-line
    By Acolyte in forum C Programming
    Replies: 8
    Last Post: 09-30-2007, 01:03 PM
  5. reading a file line by line and char *
    By odysseus.lost in forum C Programming
    Replies: 8
    Last Post: 05-31-2005, 09:47 AM