![]() |
| | #1 |
| Darkness Prevails Join Date: Oct 2006 Location: Houston, Texas
Posts: 174
| read / write binary files Code: #include <iostream>
#include <string>
#include <fstream>
struct DATA
{
std::string s1;
std::string s2;
int i1;
int i2;
std::string s3;
double d1;
double d2;
std::string s4;
};
void Save(DATA &d)
{
std::ofstream oFile("data.bin", std::ios::out | std::ios::binary);
oFile.write( (char*)&d, sizeof(d) );
oFile.close();
return;
}
void Load(DATA &d)
{
std::ifstream iFile("data.bin", std::ios::in | std::ios::binary);
iFile.read( (char*)&d, sizeof(d) );
iFile.close();
return;
}
void Display(DATA &d)
{
std::cout<<"string 1 = " <<d.s1 <<"\n"
<<"string 2 = " <<d.s2 <<"\n"
<<"integer 1 = " <<d.i1 <<"\n"
<<"integer 2 = " <<d.i2 <<"\n"
<<"string 3 = " <<d.s3 <<"\n"
<<"double 1 = " <<d.d1 <<"\n"
<<"double 2 = " <<d.d2 <<"\n"
<<"string 4 = " <<d.s4 <<"\n\n\n\n";
return;
}
int main()
{
DATA x, y;
x.s1 = "This is some text";
x.s2 = "This is some more text";
x.i1 = 5;
x.i2 = 55423;
x.s3 = "And some more text";
x.d1 = 87.12;
x.d2 = 1123.542;
x.s4 = "Wait! Here's some more text!!";
Display(x);
Save(x);
Load(y);
Display(y);
return 0;
}
#2 : Is this legal / safe? Last edited by Dark_Phoenix; 06-21-2009 at 04:21 AM. |
| Dark_Phoenix is offline | |
| | #2 |
| Kernel hacker Join Date: Jul 2007 Location: Farncombe, Surrey, England
Posts: 15,686
| What you are doing is not legal. You are essentially storing the internal data parts of string class, which IS NOT the string itself. Most of the time, the string will be stored as a pointer to the actual string data. So you'd be storing the pointer. When the data is being read back, you read back the pointer again. If you do this after destroying the original string (or after restarting the application), the pointer will no longer point to the value of the original string. You supply the size of d to read/write, so that's how it knows (but of course, sizeof(std::string) will be something like 8 or 16, no matter if you have a single character or 500 characters in the string. Becuase the string class itself doesn't store the whole string - only a pointer to strings. If you want to do this as a binary file, you have two choices: 1. Make it a POD structure - that is, do not use anything that is a class in the storage structure. 2. Use serialization - produce a pair input/output functions that stores the individual components in a form that you can read back reliably. -- Mats
__________________ Compilers can produce warnings - make the compiler programmers happy: Use them! Please don't PM me for help - and no, I don't do help over instant messengers. |
| matsp is offline | |
| | #3 |
| Darkness Prevails Join Date: Oct 2006 Location: Houston, Texas
Posts: 174
| Thanks. serialization is what I have been doing when working with std::strings, was just playing around with some ideas. I had a feeling that this would not work right, just did not quite understand what was going on "behind the scenes". Just so that I understand correct.... If I were to change the std::strings to char arrays, then this would work? |
| Dark_Phoenix is offline | |
| | #4 | |
| Kernel hacker Join Date: Jul 2007 Location: Farncombe, Surrey, England
Posts: 15,686
| Quote:
By the way, if you split your test-program so that it exits after save, and then loads in a second process, you will see that it doesn't work, even if your current example appears to work. -- Mats
__________________ Compilers can produce warnings - make the compiler programmers happy: Use them! Please don't PM me for help - and no, I don't do help over instant messengers. | |
| matsp is offline | |
| | #5 |
| Darkness Prevails Join Date: Oct 2006 Location: Houston, Texas
Posts: 174
| OK, I got it... I split my test pogram like you suggested and I see what you mean. So now I have Code: struct DATA
{
char s1[30];
char s2[30];
int i1;
int i2;
char s3[30];
double d1;
double d2;
char s4[30];
};
int main()
{
DATA x, y;
strcpy_s(x.s1, sizeof(x.s1), "This is some text");
strcpy_s(x.s2, sizeof(x.s2), "This is some more text");
x.i1 = 5;
x.i2 = 55423;
strcpy_s(x.s3, sizeof(x.s3), "And some more text");
x.d1 = 87.12;
x.d2 = 1123.542;
strcpy_s(x.s4, sizeof(x.s4), "Wait! Here's some more text!!");
Display(x);
Save(x);
Load(y);
Display(y);
return 0;
}
|
| Dark_Phoenix is offline | |
| | #6 |
| The superheterodyne. Join Date: Dec 2005 Location: Ireland
Posts: 2,205
| You could always template the structure so it will work with string arrays of different sizes. Though, of course, the template size will need to be known at compile time and the functions will have to be templated too. Code: template<int arrSize>
struct DATA
{
char s1[arrSize];
char s2[arrSize];
int i1;
int i2;
char s3[arrSize];
double d1;
double d2;
char s4[arrSize];
};
...
int main() {
DATA<30> x, y;
// etc...
return 0;
}
__________________ I blag! |
| twomers is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Merge Binary Files | chinook86 | C Programming | 7 | 01-21-2008 02:19 PM |
| Reading Binary files | earth_angel | C++ Programming | 10 | 07-12-2005 06:48 AM |
| Binary Files | Axpen | C Programming | 14 | 08-12-2004 08:41 PM |
| How to store n write binary file? | megablue | C Programming | 4 | 10-23-2003 03:53 AM |
| Serial Communications in C | ExDigit | Windows Programming | 7 | 01-09-2002 10:52 AM |