Thread: Why would ofstream not work sometimes?

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

    Unhappy Why would ofstream not work sometimes?

    Check out the following code:

    Code:
    obook.write(reinterpret_cast< const char * >(&newBook), sizeof(Book));
    ...where obook is an ofstream variable that opens a file using ios::ate and newBook is an instance of a class I made.

    The problem is that when I write to the file, around 70% of the time, it will work. There is however, a good 30% of the time where it just writes garbage. Even when I'm entering the exact same data twice (exactly the same except the key field). Why would this happen?

    Has anyone ever had this problem? I'd appreciate your insights. Thanks.
    Excuse me, while I water my money tree.

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Are you ensuring the state of obook is still good()?
    Is obook opened in binary?

    gg

  3. #3
    Registered User johnnyd's Avatar
    Join Date
    Mar 2002
    Posts
    70
    No it's not being opened in binary. It's in text mode. Here's how I play with it:

    Code:
    obook.open("books.dat", ios::ate);
    if (obook){
       newBook = Book(isbn, author, title, publisher, pPlace, status, year, copy);
       obook.write(reinterpret_cast< char * >(&newBook), sizeof(Book));
       obook.close();
       newBook.show();
       cout<<"\n\nBook data written successfully.";
       getch();
       }
    else{
       cout<<"\n\nCannot open transaction file."<<endl;
       getch();
       return;
       }
    That's pretty harmless isn't it? I mean it works most of the time without a problem! I just don't understand why simple code can go rouge sometimes.

    As for making sure if it is still good(), to be perfectly honest with you, I was never taught that. What's that?

    Thanks again Codeplug.
    Excuse me, while I water my money tree.

  4. #4
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    As Codeplug says, you should open the file in binary mode:

    obook.open("books.dat", ios::ate | ios::binary);

  5. #5
    Registered User johnnyd's Avatar
    Join Date
    Mar 2002
    Posts
    70
    I've actually tried that. It doesn't work. And exactly as how you typed it too!
    Excuse me, while I water my money tree.

  6. #6
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    The reason it is only working sometimes is because you are not opening the file in binary mode. When you use text mode, any output can be modified so that newlines are represented correctly for the native OS.
    When you read the help for ostream::write(), it says:
    If the underlying file was opened in text mode, additional carriage return characters may be inserted.
    So, if any of the bytes in your class contained 0x0A (line feed), a 0x0D (carriage return) is inserted before it to make it look like a true "newline" in DOS/Windows.

    If you aren't reading and writting text, you must use binary.

    gg

  7. #7
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    If you have an existing data file that was created with text-mode code, consider it corrupted and start fresh.

    If you are still having problems, then post your program and steps to repro the problem - we'll figure it out.

    gg

  8. #8
    Registered User johnnyd's Avatar
    Join Date
    Mar 2002
    Posts
    70
    When you say text, do you mean that all of the variables in the class should be of the char* type? or do you mean text as in a literal string like "The quick brown fox was nuked by the lazy dog"?
    Excuse me, while I water my money tree.

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

    Starting afresh... (I wish they told us these things in school and in books)
    Excuse me, while I water my money tree.

  10. #10
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    When you open an [o,i]fstream without ios::binary, then you opened the file in text-mode.

    (I edited my last post)

    gg

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

    Thumbs up

    I just tested it and it works. All the time.

    I've come to realise why binary mode wasn't working for me. It was because I used fstream to create the file handler, and not ofstream. ofstream works beautifully. But I find that rather curious though. If you have any Idea why that would happen, please comment. A classmate is reading these posts as well, so it would benefit both of us.

    Thanks yet again Codeplug. You are for me now what Prelude was for me last year. You guys rock.
    Excuse me, while I water my money tree.

  12. #12
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    With fstream you might try this:
    obook.open("books.dat", ios::ate | ios::out | ios::binary);

    And then for reading:
    obook.open("books.dat", ios::in | ios::binary);

  13. #13
    Registered User johnnyd's Avatar
    Join Date
    Mar 2002
    Posts
    70
    That's interesting Swoopy, I've never thought of that one. I'll give it a shot.
    Excuse me, while I water my money tree.

  14. #14
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    You mean "why text mode" wasn't working for you?

    There isn't any difference between ofstream and fstream except ofstream includes ios::out in it's open mode by default (and fstream includes ifstream interfaces as well). In other words, these two declarations will behave exactly the same:
    Code:
    fstream out("data.dat",ios::out);
    ofstream out("data.dat");
    That goes for any other mode flags you use, as long as the fstream version has ios::out.

    gg

  15. #15
    Registered User johnnyd's Avatar
    Join Date
    Mar 2002
    Posts
    70
    Got it. It's a shame though that C's implementation of files was so much simpler and more reliable. I get the feeling that somehow they were trying to reinvent the wheel with the text mode and it didn't work out so well - as far as standardisation is concerned anyways.
    Excuse me, while I water my money tree.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. getline() don't want to work anymore...
    By mikahell in forum C++ Programming
    Replies: 7
    Last Post: 07-31-2006, 10:50 AM
  2. Why don't the tutorials on this site work on my computer?
    By jsrig88 in forum C++ Programming
    Replies: 3
    Last Post: 05-15-2006, 10:39 PM
  3. Problems in getting OpenGL to work
    By zonf in forum C Programming
    Replies: 5
    Last Post: 02-13-2006, 04:48 AM
  4. Why won't my OpenGL work?
    By Raigne in forum C++ Programming
    Replies: 7
    Last Post: 11-26-2005, 11:53 AM
  5. Replies: 9
    Last Post: 06-06-2002, 07:03 PM