By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,127 Members | 1,127 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,127 IT Pros & Developers. It's quick & easy.

Reading and Writing to Binary Files

P: n/a
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::out | 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);
}

Jul 22 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a
> 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
Jul 22 '05 #2

P: n/a
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
Jul 22 '05 #3

P: n/a
> 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
Jul 22 '05 #4

P: n/a
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

Jul 22 '05 #5

P: n/a
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
Jul 22 '05 #6

P: n/a
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
kb******@gascad.at
Jul 22 '05 #7

P: n/a
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
Jul 22 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.