473,320 Members | 1,922 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Loading/Saving a structure using <fstream>

Hi,

I have always used fopen and FILE* to load and save structures to file.
I am trying to convert all the older code to use proper C++ calls...
the following code works properly but I would like to know if I am
using the fstream methods properly. (as long as I am cleaning up I
might as well do it right). By the way, this is just a bogus example
with a structure, values and filename for demonstration purposes.

PS-> I have a funny feeling casting my structure to a char* is the
wrong approach! :)

#include <iostream>
#include <fstream>

struct stAnything
{
int nInteger;
long lLong;
char cChar;
double dDouble;
};

int main(void)
{
std::string sFilename = "C:/test.bin";
stAnything stSomeStructure;

stSomeStructure.nInteger = 5; // bogus values
stSomeStructure.lLong = 10;
stSomeStructure.cChar = 'A';
stSomeStructure.dDouble = 5.1;

// Save the structure to a binary file
std::ofstream outFile;
outFile.open(sFilename.c_str(), std::ofstream::out |
std::ofstream::binary);
if (!outFile.is_open())
{
std::cout << "Could not open the file for output." << std::endl;
return 1;
}
outFile.write((const char *) &stSomeStructure, sizeof(stAnything));
outFile.close();

// Clear the structure
stSomeStructure.nInteger = 0;
stSomeStructure.lLong = 0;
stSomeStructure.cChar = ' ';
stSomeStructure.dDouble = 0.0;

// Load the structure from a binary file
std::ifstream inFile;
inFile.open(sFilename.c_str(), std::ofstream::in |
std::ofstream::binary);
if (!inFile.is_open())
{
std::cout << "Could not open the file for input." << std::endl;
return 1;
}
inFile.read((char *) &stSomeStructure, sizeof(stAnything));
inFile.close();

// Show the loaded contents
std::cout << "{" << stSomeStructure.nInteger << ", " <<
stSomeStructure.lLong << ", " <<
stSomeStructure.cChar << ", " <<
stSomeStructure.dDouble << "} " << std::endl;
return 0;
}

Dec 1 '05 #1
4 7823
On 2005-12-01, ad***********@gmail.com <ad***********@gmail.com> wrote:
I have always used fopen and FILE* to load and save structures
to file.
The approach has the same drawbacks in C++ as it did in C. It's
not portable. It won't work at all for structs that aren't Plain
Old Data types.
I am trying to convert all the older code to use proper C++
calls...
I'm not sure it's really an improvement over the original C.

You may want to read about serialization. Reading and writing
your structs as plain old text won't be as compact, but it's
quite portable, and gives clients the benefit of human-readable
data files.
the following code works properly but I would like to know if I
am using the fstream methods properly. (as long as I am
cleaning up I might as well do it right). By the way, this is
just a bogus example with a structure, values and filename for
demonstration purposes.

PS-> I have a funny feeling casting my structure to a char* is
the wrong approach! :)
It's normally a bad idea. In this case, it's doesn't make your
code any less portable. But prefer C++ style casts intead of the
C-style cast used.
outFile.write((const char *) &stSomeStructure, sizeof(stAnything));


outFile.write(reinterpret_cast<const char *>(&stSomeStructure)
, sizeof(stAnything));

--
Neil Cerutti
Dec 1 '05 #2
ad***********@gmail.com wrote:
Hi,

I have always used fopen and FILE* to load and save structures to file.
I am trying to convert all the older code to use proper C++ calls...
the following code works properly but I would like to know if I am
using the fstream methods properly. (as long as I am cleaning up I
might as well do it right). By the way, this is just a bogus example
with a structure, values and filename for demonstration purposes.
See the FAQ for more robust techniques that will work with all classes
and structs not just ones without virtual functions or, e.g.,
std::vectors:

http://www.parashift.com/c++-faq-lit...alization.html

And check out Boost's serialization library:

http://boost.org/libs/serialization/doc/index.html
PS-> I have a funny feeling casting my structure to a char* is the
wrong approach! :)
For binary mode, you'll have to do that cast eventually.
#include <iostream>
#include <fstream>

struct stAnything
{
int nInteger;
long lLong;
char cChar;
double dDouble;
};

int main(void)
Using void like that is an "abomination"
(http://www.research.att.com/~bs/sibling_rivalry.pdf).
{
std::string sFilename = "C:/test.bin";
Should be const.
stAnything stSomeStructure;

stSomeStructure.nInteger = 5; // bogus values
stSomeStructure.lLong = 10;
stSomeStructure.cChar = 'A';
stSomeStructure.dDouble = 5.1;

// Save the structure to a binary file
std::ofstream outFile;
outFile.open(sFilename.c_str(), std::ofstream::out |
std::ofstream::binary);
Prefer to open and close with the constructor and destructor,
respectively, unless you need to do differently. (In this test program,
you would actually need to close the output file manually or else move
the serialization to a separate function so the file is closed via the
destructor when the function returns.)
if (!outFile.is_open())
Better would be:

if( !outFile )
{
std::cout << "Could not open the file for output." << std::endl;
return 1;
}
outFile.write((const char *) &stSomeStructure, sizeof(stAnything));
You didn't check that the write succeeded, and you should use C++-style
casts - reinterpret_cast would be appropriate here to signal a
potentially shady conversion.

Similar comments apply to the read portion.
outFile.close();

// Clear the structure
stSomeStructure.nInteger = 0;
stSomeStructure.lLong = 0;
stSomeStructure.cChar = ' ';
stSomeStructure.dDouble = 0.0;

// Load the structure from a binary file
std::ifstream inFile;
inFile.open(sFilename.c_str(), std::ofstream::in |
std::ofstream::binary);
if (!inFile.is_open())
{
std::cout << "Could not open the file for input." << std::endl;
return 1;
}
inFile.read((char *) &stSomeStructure, sizeof(stAnything));
inFile.close();

// Show the loaded contents
std::cout << "{" << stSomeStructure.nInteger << ", " <<
stSomeStructure.lLong << ", " <<
stSomeStructure.cChar << ", " <<
stSomeStructure.dDouble << "} " << std::endl;
return 0;
}


You might also be interested in this section of the FAQ:

http://www.parashift.com/c++-faq-lite/input-output.html

Cheers! --M

Dec 1 '05 #3
mlimber <ml*****@gmail.com> wrote:
ad***********@gmail.com wrote:
// Save the structure to a binary file
std::ofstream outFile;
outFile.open(sFilename.c_str(), std::ofstream::out |
std::ofstream::binary);


Prefer to open and close with the constructor and destructor,
respectively, unless you need to do differently. (In this test program,
you would actually need to close the output file manually or else move
the serialization to a separate function so the file is closed via the
destructor when the function returns.)


Alternately, he could wrap the code that uses outFile in an extra set of
{ }'s to limit its scope:

// ...
stSomeStructure.dDouble = 5.1;

{
// Save the structure to a binary file
std::ofstream outFile(sFilename.c_str(),
std::ofstream::out | std::ofstream::binary);
if (!outFile)
{
std::cout << "Could not open the file for output." << std::endl;
return 1;
}
outFile.write((const char *) &stSomeStructure, sizeof(stAnything));
}

// rest of code
--
SLuGHEAd78 | "Today, if you are not confused, you are
A.K.A. DJ Slant Eye, Chudmuffin, | just not thinking clearly."
Marcus Kwok, Silly Chink, Nuprin | -U. Peter
Dec 1 '05 #4
Thanks for all the suggestions... they seem to do the trick.

Dec 1 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Armando | last post by:
Hallo ! I habe some error in my programm,because i use <fstream.h>,I want to use <fstream> but i don´t know which fonctions i must modify in my program ? Thanks you for your help. Armando.
11
by: Charles L | last post by:
I have read that the inclusion of <fstream.h> makes the inclusion of <iostream.h> unnecessary. Is this correct? Charles L
1
by: Macca | last post by:
Hi, I have been using <fstream.h> in stdafx.h,(i'm using MFC) to output to text files. I have now started to use vectors and when i added #include <vector> using namespace std; to...
4
by: nils | last post by:
Hi all, Recently I started migrating a gcc project to Visual Studio C++ (dotnet). The problem is that I cannot include any iostream header-file: #include <fstream> int main (int argc, char *...
4
by: Falos425 | last post by:
Okay, I've got a driver.cpp, a section.cpp, and a section.h because I've got a 'section' class. I have an #include <fstream> in the section.h and then section.cpp has an #include "section.h" ...
31
by: grubbymaster | last post by:
hello i'm extracting from a file numbers that are stored on each line. this is the only way i know to extract each line at a time from a file , using <fstream> <ostream> : char buffer; ...
5
by: neowillis | last post by:
code: #include <iostream> #include <fstream> #include <string> using namespace std; int main() {
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.