Thread: problem with fstream

  1. #1
    Registered User
    Join Date
    Dec 2006
    Posts
    8

    problem with fstream

    Hi,

    I have very strange problem with std::fstream. I want to read a simple two-column space-separated file with the following code:

    #include <iostream>
    #include <fstream>

    Code:

    Code:
    int main() { 
      std::ifstream file("file.txt");
      unsigned long oldval;
      unsigned long newval;
      while(!file.eof()) {
        file >> oldval;
        file >> newval;
        std::cout << oldval << " " << newval << std::endl;
      }
    }
    The file.txt contains ten lines only:

    Code:

    3036679276 4677957
    3233819949 6457113
    3602920021 7347886
    6236944672 16846074
    2487223488 3069408
    2818574689 4363018
    5419052468 13941073
    9172944933 31529903
    2818574690 4363020
    9172944938 31529909

    As output, I get an endless printing of the 3rd line. I have tried a lot of variants, like:

    Code:
    while(file>>oldval>>newval)
    or
    while(file.good())
    i also have printed the get pointer with file.tellg() and always get -1. Lastly, i tried reading one line, then created a stringstream and read from it:

    Code:
    int main()
    {
       std::ifstream file("file.txt");
       unsigned long oldval;
       unsigned long newval;
       std::string line;
    
       while(!file.eof()) {
          std::getline(file, line);
          std::stringstream linestream(line);
          linestream >> oldval;
          linestream >> newval;
          std::cout << oldval << " " << newval << std::endl;
       }
    }
    i get the following:

    I get the following:

    3036679276 4677957
    3233819949 6457113
    3602920021 7347886
    3602920021 7347886
    2487223488 3069408
    2818574689 4363018
    2818574689 4363018
    2818574689 4363018
    2818574690 4363020
    2818574690 4363020
    2818574690 4363020

    It looks like the seek internal pointer of fstream is not moving. Any clues about this? I'm in RH with GCC3.4. ????? I don't get it :S Any ideas??? I'm starting to believe that my computer is possessed

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > 6236944672
    Probably because this doesn't fit into an unsigned long, and you're getting a conversion error.

    > while(!file.eof())
    This is bad, see the FAQ

    Maybe
    Code:
       while( std::getline(file, line) ) {
          std::stringstream linestream(line);
          if ( linestream >> oldval >> newval ) {
             std::cout << oldval << " " << newval << std::endl;
          } else {
             std::cout << "Bad input" << std::endl;
          }
       }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Dec 2006
    Posts
    8

    Wink Re: Problem with fstream

    Thanks a lot for your time. I changed the data type to long long and it worked.

    >> while(!file.eof())
    > This is bad, see the FAQ

    The eof that the FAQ talks about is from C, i think that the std::fstream::eof() function solves that problems, at least in my program works fine. Do you know if this is true for C++ (that the efo() works fine)?

    Thanks

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    There are similar issues with using eof() to control a loop in C++, although they are not exactly the same. If your original code was working, you would likely be outputting the last pair of values twice. Can you post your current version?

  5. #5
    Registered User
    Join Date
    Dec 2006
    Posts
    8
    Hi, this is my last working version

    Code:
    int main() { 
      std::ifstream file("file.txt");
      unsigned long long oldval, newval;
    
      while(!file.eof()) {
        file >> oldval >> newval;
        std::cout << oldval << " " << newval << std::endl;
      }
    }
    The values are printed only once. It seems to work fine but I don't know if there are issues with using it.

    Thanks

  6. #6
    Registered User
    Join Date
    Dec 2006
    Posts
    8
    Wait! You're right, my final version is not that one, is this one:

    Code:
    int main() { 
      std::ifstream file("file.txt");
      unsigned long long oldval, newval;
    
      while(!file.eof()) {
        if(file >> oldval >> newval) {
          std::cout << oldval << " " << newval << std::endl;
        } else {
          std::cout << "bad input" << std::endl;
        }
      }
    }
    with the previous version I do get the last line printed twice. With this one I get a bad input instead of the repetition of the last line. Can you explain what does this happens? Or where can we read about it? I'd really appreciate it.

    Thanks for your time.

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> where can we read about it?
    I have never seen it explained correctly, although I'm sure it is somewhere. I have explained it a couple times, but it would be hard to search for since I've posted more than a few times on here, and more than a few times on the subject. I will search for the thread or give an explanation later (tomorrow my time).

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > while(!file.eof())
    Why are you still doing this? It's been explained enough already.

    feof(), whether in C or C++ is a state (of past events), not a prediction (for future actions).

    The end of file state is only set by you performing some read action, namely this
    if(file >> oldval >> newval)

    Your bad input message at this point really means end of file, not conversion error.

    Which if you made your else look like this
    Code:
    else {
      if ( file.eof() ) {
        std::cout << "EOF!!!" << std::endl;
      } else {
        std::cout << "bad input" << std::endl;
      }
    }
    What is worse, is that if you actually corrupt your file, you STILL lock up because things like
    file >> oldval >> newval
    do NOT skip over bad input data.

    Just but a line of characters in your file instead of pairs of numbers.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM
  2. Laptop Problem
    By Boomba in forum Tech Board
    Replies: 1
    Last Post: 03-07-2006, 06:24 PM
  3. Replies: 5
    Last Post: 11-07-2005, 11:34 PM
  4. half ADT (nested struct) problem...
    By CyC|OpS in forum C Programming
    Replies: 1
    Last Post: 10-26-2002, 08:37 AM
  5. Fstream Problem
    By Xterria in forum C++ Programming
    Replies: 2
    Last Post: 08-25-2001, 11:03 PM