Thread: ofstream resetting get pointer position

  1. #1
    Registered User
    Join Date
    May 2008
    Location
    Australia
    Posts
    230

    ofstream resetting get pointer position

    First off topic name is wrong, it's meant to be: ifstream resetting get pointer position

    I'm having trouble resetting the get pointer position. I want to read a file, then set the get pointer back to the beginning of the file, so then if my function is called again it will re-read the entire file. The problem is it will only read it once, and for some reason it won't reset properly. Another thing, I'm getting odd output. It will paste everything in the file, then it will repeat the very last line once, this is an example output:

    Say the file contains:

    Code:
    www.hi.com
    www.hello.com
    www.sup.com
    The output will be like this:

    Code:
    www.hi.com
    www.hello.com
    www.sup.com
    www.sup.com
    It always repeats the last line for some odd reason that I cannot see. Ok here are the important bits of code to help diagnose the problem, thanks!:

    Code:
    class Crawl {
    
    public:
    	Crawl();
    	void PrintMenu();
    
    private:
    	ofstream writeStream;
    	ifstream readStream;
    
    };
    
    Crawl::Crawl() {
    	writeStream.open("crawler.txt", ios_base::app);
    	readStream.open("crawler.txt");
    }
    
    void Crawl::PrintCrawl() {
    
    	string x;
    
    	while (!readStream.eof()) {
    		readStream >> x;
    		cout << x << "\n";
    	}
    
    	readStream.seekg(0, ios_base::beg);
    	readStream.clear();
    
    }
    Last edited by pobri19; 12-08-2008 at 05:33 AM. Reason: Topic name was wrong
    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, because the last time you try to read something, it gets an EOF, then you still print the content of x, which is the old value from the last read.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    May 2008
    Location
    Australia
    Posts
    230
    Oh.. Makes sense, ok well that's an easy fix, but that doesn't fix the reason why it won't read more than once

    Code:
    	while (!readStream.eof()) {
    		readStream >> x;
    		if (!readStream.eof())
    			cout << x << "\n";
    	}
    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Or, a "better" fix:
    Code:
    while(readstream >> x)
    {
    ...
    }
    I don't see anything directly wrong, but perhaps you should try doing clear() first, then seekg(), as it may be that seekg() doesn't "do it's thing" if the stream is not in a good state.


    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    May 2008
    Location
    Australia
    Posts
    230
    Yep that worked, thanks matsp you're a genius
    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Incidentally, you might want to use the constructor initialisation list, e.g.,
    Code:
    Crawl::Crawl() : writeStream("crawler.txt", ios_base::app), readStream("crawler.txt") {}
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    May 2008
    Location
    Australia
    Posts
    230
    Quote Originally Posted by laserlight View Post
    Incidentally, you might want to use the constructor initialisation list, e.g.,
    Code:
    Crawl::Crawl() : writeStream("crawler.txt", ios_base::app), readStream("crawler.txt") {}
    What would be the advantage of that?
    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by pobri19
    What would be the advantage of that?
    It would be slightly more efficient since you create the member streams with what you want instead of default constructing them and only then opening them.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    May 2008
    Location
    Australia
    Posts
    230
    So if I use the initialisation list (which I've never known about until now lol) it will open the files before a Crawl object is actually declared (which doesn't make sense to me, so I'm assuming this is wrong - because the objects etc don't get created until an instance of that object is created so therefore the constructor has nothing to change until it has an object to work with), and before the constructor of that class is actually called? Is that the difference?
    Last edited by pobri19; 12-08-2008 at 09:02 AM.
    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by pobri19
    So if I use the initialisation list (which I've never known about until now lol) it will open the files before a Crawl object is actually declared, and before the constructor of that class is actually called? Is that the difference?
    When the default constructor for Crawl is invoked to create a Crawl object, the writeStream and readStream member variables of that new Crawl object would be initialised by opening the corresponding file. With your original code, there would be an unnecessary gap between the time that they are created and the time that they represent an open input/output stream. During that gap, the stream objects would exist with default states that would immediately be replaced by the desired states.

    Also, since these stream objects are non-copyable, it might be good to declare the Crawl copy constructor and copy assignment operator as private.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    Registered User
    Join Date
    May 2008
    Location
    Australia
    Posts
    230
    "Also, since these stream objects are non-copyable, it might be good to declare the Crawl copy constructor and copy assignment operator as private."

    Yeah... I have no idea how to do that I'll try and figure that out with Google. Never touched copy constructors or copy assignment operators or whatever before. Thanks for the help.
    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.

  12. #12
    Registered User
    Join Date
    May 2008
    Location
    Australia
    Posts
    230
    laserlight: What will declaring them private do?
    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by pobri19 View Post
    laserlight: What will declaring them private do?
    Make sure that no code outside of the class itself can call them - which essentially means you can't copy or assign objects of this class.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problems passing a file pointer to functions
    By smitchell in forum C Programming
    Replies: 4
    Last Post: 09-30-2008, 02:29 PM
  2. ofstream and FILE behaviour
    By MrLucky in forum C++ Programming
    Replies: 7
    Last Post: 06-21-2007, 05:45 PM
  3. Savign the position of a pointer in an input file
    By earth_angel in forum C++ Programming
    Replies: 13
    Last Post: 07-08-2005, 03:39 PM
  4. Could somebody please help me with this C program
    By brett73 in forum C Programming
    Replies: 6
    Last Post: 11-25-2004, 02:19 AM
  5. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM