Reading and Writing to Binary Files

Discussion in 'C++' started by Daniel Moree, Nov 23, 2004.

  1. Daniel Moree

    Daniel Moree Guest

    I'm working on a program that must first establish if the file exists in the
    program directory then it must open if for reading, read each line and set
    the variables then the program goes on about it's buisness.

    My problem is all the resources I have found aren't very clear on these
    things. All of them open the file then check to see if the stream is open.
    Well, the problem with using file.open("filename.dat", ios::in |
    ios::binary) is that if the file doesn't exists, it creates it
    automatically. I need to see if the file exists, if it doesn't show an error
    message, then if the file does exists, open if, read from it, then set the
    global program variables. Below is my code so far to try to get this work.

    I've marked where I needed help with // Need help here and many question
    marks
    Hopefully you guys will get a good view of what i'm doing, just a basic
    console app in MSVC++ that pulls information in a binary file then if that
    is successful allow you to set the variables to something else. Then run the
    program again and view the information then set it to something different.

    ===== MAIN.CPP =====
    #include <iostream.h>
    #include <fstream.h>
    #include <iomanip.h>

    // variables
    int Box_X;
    int Box_Y;
    int Box_Z;
    float input_X;
    float input_Y;
    float input_Z;
    char* filename = {"main.dat"};

    // Functions
    bool pullconfig();
    bool setconfig();

    // main function
    int main(){
    cout << "Pulling configuration information...\n";
    if(pullconfig() == false){
    cout << "\nError opening \"main.dat\" file: Does Not Exist!\n";
    return 0;
    }
    cout << "Configuration pulled successfully!\n";
    cout << "\nBox_X = " << Box_X << "; Box_Y = " << Box_Y << "; Box_Z = "
    << Box_Z << "\n";
    cout << "Set Box_X to: ";
    cin >> input_X;
    cout << "Set Box_Y to: ";
    cin >> input_Y;
    cout << "Set Box_Z to: ";
    cin >> input_Z;
    if(setconfig() == false){
    cout << "\nError setting configuration information!\n";
    return 0;
    }
    cout << "\nNew Configuration Set Successfully!";
    return 0;
    }

    bool pullconfig(){
    ifstream fin(filename, ios::in | ios::binary);
    if(!fin.is_open()){
    return(false);
    }

    // Need Help here for pulling info and setting it to Box_X, Box_Y, and
    Box_Z ????????????????????????????????
    return(true);
    }

    bool setconfig(){
    ofstream fout(filename, ios::eek:ut | ios:binary);
    if(!fout.is_open()){
    return(false);
    }
    fout << "Box_X = " << input_X << "\n";
    fout << "Box_Y = " << input_Y << "\n";
    fout << "Box_Z = " << input_Z << "\n";
    fout.close();
    return(true);
    }
    Daniel Moree, Nov 23, 2004
    #1
    1. Advertising

  2. > I'm working on a program that must first establish if the file exists in the
    > program directory then it must open if for reading, read each line and set
    > the variables then the program goes on about it's buisness.
    >
    > My problem is all the resources I have found aren't very clear on these
    > things. All of them open the file then check to see if the stream is open.
    > Well, the problem with using file.open("filename.dat", ios::in |
    > ios::binary) is that if the file doesn't exists, it creates it
    > automatically.


    This is not the standard behavior.

    # include <fstream>

    int main
    {
    std::ifstream ifs("myfile");

    if ( ! ifs )
    {
    // file does not exist or some other error
    }
    }


    > I need to see if the file exists, if it doesn't show an error
    > message, then if the file does exists, open if, read from it, then set the
    > global program variables. Below is my code so far to try to get this work.


    If your standard library does that, change it. If you can't use
    implementation-defined functions which will probably give you many more
    options, such as checking if a file exists.

    > ===== MAIN.CPP =====
    > #include <iostream.h>
    > #include <fstream.h>
    > #include <iomanip.h>


    Non standard.

    # include <iostream>
    # include <fstream>
    # include <iomanip>

    using namespace std;

    This could be the source of your problem. I put the using declaration
    here to make the code work, but do read about its associated problems.

    > // variables
    > int Box_X;
    > int Box_Y;
    > int Box_Z;
    > float input_X;
    > float input_Y;
    > float input_Z;
    > char* filename = {"main.dat"};


    Global variables are best avoided.

    > // Functions
    > bool pullconfig();
    > bool setconfig();
    >
    > // main function
    > int main(){


    <snip>

    > }
    >
    > bool pullconfig(){
    > ifstream fin(filename, ios::in | ios::binary);
    > if(!fin.is_open()){
    > return(false);
    > }
    >
    > // Need Help here for pulling info and setting it to Box_X, Box_Y, and
    > Box_Z ????????????????????????????????


    I don't know about the file format, but have a look at this.

    // file.txt
    123
    456
    789


    // main.cpp
    # include <iostream>
    # include <fstream>
    # include <sstream>
    # include <string>

    int main()
    {
    std::ifstream ifs("file.txt");
    int box_x = 0, box_y = 0, box_z = 0;

    if ( ! ifs )
    {
    std::cout << "There was an error with the file";
    return 1;
    }

    std::string line;
    std::istringstream iss;

    std::getline(ifs, line);
    iss.str(line);
    iss >> box_x;

    std::getline(ifs, line);
    iss.str(line);
    iss >> box_y;

    std::getline(ifs, line);
    iss.str(line);
    iss >> box_z;

    std::cout << box_x << box_y << box_z;
    }

    (untested and lots of error checking left out)

    Jonathan
    Jonathan Mcdougall, Nov 23, 2004
    #2
    1. Advertising

  3. Daniel Moree

    Daniel Moree Guest

    Thanks for your help. This is the best response i've gotten yet. I'm using
    the C++ Primer Plus Third Edition. I tried using the standard namespace and
    i had the same errors so i figured that it wouldn't make a difference
    whether I used #include <iostream.h> or #include <iostream> using namespace
    std;

    I'll try messing with this and see If I can get any of it to work for me.
    I'll post back and let you know

    Daniel Moree
    Daniel Moree, Nov 23, 2004
    #3
  4. > I tried using the standard namespace and
    > i had the same errors so i figured that it wouldn't make a difference
    > whether I used #include <iostream.h> or #include <iostream> using namespace
    > std;


    The difference is simple : the former is not standard and the latter is.
    The next time you get errors when using standard headers, post it here
    and we will be able to help you.

    > I'll try messing with this and see If I can get any of it to work for me.
    > I'll post back and let you know


    Good.


    Jonathan
    Jonathan Mcdougall, Nov 23, 2004
    #4
  5. Daniel Moree

    Daniel Moree Guest

    I've messed around with it and checked out my copy of MSDN and can't quit
    figure out the error.

    this is the file:
    #include <iostream>
    #include <fstream>
    #include <sstream>
    #include <string>

    using namespace std;

    int main()
    {
    ifstream fin("main.dat");
    int box_x = 0, box_y = 0, box_z = 0;

    if(!fin ){
    cout << "There was an error with the file\n";
    return 1;
    } else {
    cout << "File found! Printing Contents:\n\n";

    string line;
    istringstream iss;

    getline(fin, line);
    iss.str(line);
    iss >> box_x;

    getline(fin, line);
    iss.str(line);
    iss >> box_y;

    getline(fin, line);
    iss.str(line);
    iss >> box_z;

    cout << "Box_X: " << box_x << "\n";
    cout << "Box_Y: " << box_y << "\n";
    cout << "Box_Z: " << box_z << "\n";

    cout << "\nEnd Of File\n";

    return 0;
    }
    }

    contents of my data file:
    9
    23
    3666

    Problem: I run it, I pull the Box_X variable, but I don't get the
    information from the second line nor the third. Just get 0 or NULL
    I though maybe somewhere I would have to change lines in the getline but it
    changes on it's own and pulls nothing from the next line,
    maybe I need to reset a variable each time or something. Check it out, see
    what's up.

    Daniel
    Daniel Moree, Nov 23, 2004
    #5
  6. Daniel Moree wrote:
    > I've messed around with it and checked out my copy of MSDN and can't quit
    > figure out the error.
    >
    > this is the file:
    > #include <iostream>
    > #include <fstream>
    > #include <sstream>
    > #include <string>
    >
    > using namespace std;
    >
    > int main()
    > {
    > ifstream fin("main.dat");
    > int box_x = 0, box_y = 0, box_z = 0;
    >
    > if(!fin ){
    > cout << "There was an error with the file\n";
    > return 1;
    > } else {
    > cout << "File found! Printing Contents:\n\n";
    >
    > string line;
    > istringstream iss;
    >
    > getline(fin, line);
    > iss.str(line);
    > iss >> box_x;


    iss.clear();

    > getline(fin, line);
    > iss.str(line);
    > iss >> box_y;


    iss.clear();

    > getline(fin, line);
    > iss.str(line);
    > iss >> box_z;


    iss.clear();

    > cout << "Box_X: " << box_x << "\n";
    > cout << "Box_Y: " << box_y << "\n";
    > cout << "Box_Z: " << box_z << "\n";
    >
    > cout << "\nEnd Of File\n";
    >
    > return 0;
    > }
    > }
    >
    > contents of my data file:
    > 9
    > 23
    > 3666
    >
    > Problem: I run it, I pull the Box_X variable, but I don't get the
    > information from the second line nor the third. Just get 0 or NULL


    Calling clear() on the stream resets its state to good. For a reason I
    cannot explain (perhaps someone else could enlighten us), the compiler I
    use (.net) seems to set the eof bit after reading from the
    istringstream. I don't have other compilers handy to test, but calling
    clear() should make it work (it does on my machine).

    Jonathan
    Jonathan Mcdougall, Nov 23, 2004
    #6
  7. Daniel Moree wrote:
    >
    > I've messed around with it and checked out my copy of MSDN and can't quit
    > figure out the error.
    >
    > this is the file:
    > #include <iostream>
    > #include <fstream>
    > #include <sstream>
    > #include <string>
    >
    > using namespace std;
    >
    > int main()
    > {
    > ifstream fin("main.dat");
    > int box_x = 0, box_y = 0, box_z = 0;
    >
    > if(!fin ){
    > cout << "There was an error with the file\n";
    > return 1;
    > } else {
    > cout << "File found! Printing Contents:\n\n";
    >
    > string line;
    > istringstream iss;
    >
    > getline(fin, line);
    > iss.str(line);
    > iss >> box_x;
    >
    > getline(fin, line);


    iss.clear();

    > iss.str(line);
    > iss >> box_y;
    >
    > getline(fin, line);


    iss.clear();

    > iss.str(line);
    > iss >> box_z;
    >
    > cout << "Box_X: " << box_x << "\n";
    > cout << "Box_Y: " << box_y << "\n";
    > cout << "Box_Z: " << box_z << "\n";
    >
    > cout << "\nEnd Of File\n";
    >
    > return 0;
    > }
    > }
    >
    > contents of my data file:
    > 9
    > 23
    > 3666
    >
    > Problem: I run it, I pull the Box_X variable, but I don't get the
    > information from the second line nor the third.


    You first nead to clear the stringstream.
    The simplest thing is: Always use a fresh stringstream object. This
    is much less an issue, if you simply put the reading of a value into
    a function of its own. (Error handling omitted in the following)

    #include <iostream>
    #include <fstream>
    #include <sstream>
    #include <string>

    using namespace std;

    int ReadInt( ifstream& In )
    {
    int Tmp;
    string line;

    getline( In, line );
    istringstream iss( line );
    iss >> Tmp;

    return Tmp;
    }

    int main()
    {
    ifstream fin("main.dat");
    int box_x = 0, box_y = 0, box_z = 0;

    if(!fin ){
    cout << "There was an error with the file\n";
    return EXIT_FAILURE;
    }

    cout << "File found! Printing Contents:\n\n";

    box_x = ReadInt( fin );
    box_y = ReadInt( fin );
    box_z = ReadInt( fin );

    cout << "Box_X: " << box_x << "\n";
    cout << "Box_Y: " << box_y << "\n";
    cout << "Box_Z: " << box_z << "\n";

    cout << "\nEnd Of File\n";

    return EXIT_SUCCESS;
    }


    --
    Karl Heinz Buchegger
    Karl Heinz Buchegger, Nov 24, 2004
    #7
  8. Daniel Moree

    Daniel Moree Guest

    > #include <iostream>
    > #include <fstream>
    > #include <sstream>
    > #include <string>
    >
    > using namespace std;
    >
    > int ReadInt( ifstream& In )
    > {
    > int Tmp;
    > string line;
    >
    > getline( In, line );
    > istringstream iss( line );
    > iss >> Tmp;
    >
    > return Tmp;
    > }
    >
    > int main()
    > {
    > ifstream fin("main.dat");
    > int box_x = 0, box_y = 0, box_z = 0;
    >
    > if(!fin ){
    > cout << "There was an error with the file\n";
    > return EXIT_FAILURE;
    > }
    >
    > cout << "File found! Printing Contents:\n\n";
    >
    > box_x = ReadInt( fin );
    > box_y = ReadInt( fin );
    > box_z = ReadInt( fin );
    >
    > cout << "Box_X: " << box_x << "\n";
    > cout << "Box_Y: " << box_y << "\n";
    > cout << "Box_Z: " << box_z << "\n";
    >
    > cout << "\nEnd Of File\n";
    >
    > return EXIT_SUCCESS;
    > }


    Thank you! I tried using iss.clear() and got nothing, I also tried
    iss.remove() and a few other commands i though would work. I was thinking of
    creating a class to do this for me. But I guess creating another function
    will work and since It doesn't do much and resets everytime it's perfect.
    Thanks for this. I really appriciate it guys!!!!

    Daniel Moree
    Daniel Moree, Nov 24, 2004
    #8
  9. Jonathan Mcdougall wrote:
    >
    > Calling clear() on the stream resets its state to good. For a reason I
    > cannot explain (perhaps someone else could enlighten us),


    Once you know, it is actually very simple.
    As always, eof gets set when an attempt is made to read
    past the end of the stream.

    Now. When you do

    iss >> box_y;

    How does op>> detect that it has read the whole number:
    * When a character is read from the stream that can no
    longer belong to that number (such as eg. whitespace or
    a character)
    * Or when there is nothing more to read.

    How is the second case detected: This is the tricky part.
    It cannot be detected other then: when a character read operation
    fails because of eof. Thus in order to figure out that the number
    in the stream has been read completely, the op>> has to drive the
    string into an eof state in this case (that is: the stream contains
    only the number and nothing else).

    --
    Karl Heinz Buchegger
    Karl Heinz Buchegger, Nov 24, 2004
    #9
  10. Karl Heinz Buchegger wrote:
    > Jonathan Mcdougall wrote:
    >
    >>Calling clear() on the stream resets its state to good. For a reason I
    >>cannot explain (perhaps someone else could enlighten us),

    >
    >
    > Once you know, it is actually very simple.
    > As always, eof gets set when an attempt is made to read
    > past the end of the stream.
    >
    > Now. When you do
    >
    > iss >> box_y;
    >
    > How does op>> detect that it has read the whole number:
    > * When a character is read from the stream that can no
    > longer belong to that number (such as eg. whitespace or
    > a character)
    > * Or when there is nothing more to read.
    >
    > How is the second case detected: This is the tricky part.
    > It cannot be detected other then: when a character read operation
    > fails because of eof. Thus in order to figure out that the number
    > in the stream has been read completely, the op>> has to drive the
    > string into an eof state in this case (that is: the stream contains
    > only the number and nothing else).


    Perfect explanation as usual, thank you.


    Jonathan
    Jonathan Mcdougall, Nov 24, 2004
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Daniel Gowans

    Reading/Writing pure binary files

    Daniel Gowans, May 27, 2004, in forum: VHDL
    Replies:
    2
    Views:
    5,165
  2. Steve Bennett

    need help reading/writing binary

    Steve Bennett, Aug 25, 2004, in forum: Perl
    Replies:
    1
    Views:
    495
    Joe Smith
    Aug 25, 2004
  3. Louis
    Replies:
    6
    Views:
    1,088
    Sudsy
    Oct 15, 2003
  4. Ron Eggler

    writing binary file (ios::binary)

    Ron Eggler, Apr 25, 2008, in forum: C++
    Replies:
    9
    Views:
    924
    James Kanze
    Apr 28, 2008
  5. Chris Guenther

    Reading and writing a binary file

    Chris Guenther, Mar 21, 2005, in forum: Ruby
    Replies:
    12
    Views:
    310
    Pit Capitain
    Mar 23, 2005
Loading...

Share This Page