Thread: Are fstream and ofstream incompatible?

  1. #1
    Registered User johnnyd's Avatar
    Join Date
    Mar 2002
    Posts
    70

    Unhappy Are fstream and ofstream incompatible?

    Hi all...

    I have not seen a faq or post that matches my problem. Hopefully, you folks can lend me your expertise once again.

    I'm using random files to store some data. When I use ofstream to write the data to the file, it stores it just fine and ifstream variables can read it properly.

    However, if I define a variable as fstream and write to that same file, only the record which it had modified is correctly written. The rest of the file becomes garbage (as interpreted by the ifstream variable).

    In addition, when looping through the contents of the file using a while loop, the first record is skipped. Why is this? Using the same while loop with an ifstream variable finds all the records just fine! Including the first record!

    Correct me if I'm wrong, but aren't ifstream and ofstream subclasses of the fstream class? Shouldn't I be able to read the data from the file just fine with the fstream variable? Why does modifying one record corrupt the rest of the file when using fstream if it wasn't originally written by a fstream variable? Is this a known issue?

    Your insights please. Thanks in advance.
    Excuse me, while I water my money tree.

  2. #2
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Post a short section of code showing your problem.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  3. #3
    Registered User johnnyd's Avatar
    Join Date
    Mar 2002
    Posts
    70
    This works fine:

    Code:
    Book test; //Book is my custom class
    ifstream inbook("book.dat", ios::in);
    ofstream outbook "book.dat", ios::ate);
    inbook.read(reinterpret_cast< char* >(&test), sizeof(Book));
    while (!inbook.eof()){
       if (strcmp(test.getTitle(), title) == 0){
          test.setTitle(newTitle);
          outbook.seekp(inbook.tellg() - sizeof(Book));
          outbook.write(reinterpret_cast< char* >(&test), sizeof(Book));
          }
       inbook.read(reinterpret_cast< char* >(&test), sizeof(Book));
       }
    but this doesn't:

    Code:
    Book test; //Book is my custom class
    fstream fbook("book.dat", ios::binary|ios::in|ios::out);
    fbook.read(reinterpret_cast< char* >(&test), sizeof(Book));
    while (!fbook.eof()){
       if (strcmp(test.getTitle(), title) == 0){
          test.setTitle(newTitle);
          fbook.write(reinterpret_cast< char* >(&test), sizeof(Book));
          }
       fbook.read(reinterpret_cast< char* >(&test), sizeof(Book));
       }
    As you can see, the blocks of code are quite similar. The second block either skips over some of the records or corrupts the entire file. I have have since abandoned the use of fstream as it's performance seems to be inconsistent. Sometimes it works beautifully, but most times it doesn't. Even when there is no change in the code, and I have no idea why.
    Excuse me, while I water my money tree.

  4. #4
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Your first example opens the file in text mode, the second example opens the file in binary mode.
    Stick with binary and use fstream. If you open the db file anywhere else in the code using ifstream or ofstream then use:
    Code:
    ifstream inbook("book.dat", ios::binary);
    ofstream outbook "book.dat", ios::binary|ios::ate);
    Remember that ifstream will have ios::in by default and ofstream will have ios::out by default.

    The source of the corruption you were seeing was most likely due to mixing text and binary I/O to the same file.

    gg

    [EDIT]
    From your first example, you don't really need ios::ate since you modify the put-pointer explicitly before writing.
    Last edited by Codeplug; 03-19-2003 at 12:08 PM.

  5. #5
    Registered User johnnyd's Avatar
    Join Date
    Mar 2002
    Posts
    70

    Thumbs up

    Alas, I believe you have hit the nail on the head. I didn't know it made a difference. Thanks again Codeplug.

    It would seem as if I have to totally abandon the Deitel and Deitel 4th ed. It is giving me a lot of confusing information - a lot of it very misleading as I have found out in these boards. It did not make a clear distinction between the two modes aside from using the ios::binary specifier - which emptied the file each time. I'm going to have to write them.

    If I had listened to you guys sooner (and ditched the book), I would have finished this a long time ago. It makes me wonder though, aparently my lecturers didn't try these examples themselves (from the book I mean). They'd have come across the same anomalies. I guess they made the fatal mistake of assuming they would work. I have to go back and inform the rest of my class. They are all having the same issues.
    Excuse me, while I water my money tree.

  6. #6
    Registered User johnnyd's Avatar
    Join Date
    Mar 2002
    Posts
    70

    Cool

    Originally posted by Codeplug
    From your first example, you don't really need ios::ate since you modify the put-pointer explicitly before writing.
    I'm just realising that. Thanks for the keen eye.
    Excuse me, while I water my money tree.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. how to use fstream library
    By salmanriaz in forum C++ Programming
    Replies: 7
    Last Post: 03-12-2009, 07:06 AM
  2. New to fstream and ofstream
    By beene in forum C++ Programming
    Replies: 3
    Last Post: 01-22-2007, 12:34 PM
  3. Using fstream
    By Sridar in forum C++ Programming
    Replies: 5
    Last Post: 06-30-2005, 12:36 PM
  4. Why won't fstream file open?
    By Brown Drake in forum C++ Programming
    Replies: 4
    Last Post: 11-20-2001, 11:30 AM
  5. Fstream Problem
    By Xterria in forum C++ Programming
    Replies: 2
    Last Post: 08-25-2001, 11:03 PM