Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Saving basic data to a file...

Status
Not open for further replies.

benb777

Programmer
Dec 30, 2002
7
0
0
US
Hi,
I am a newbie programmer and i am wondering if anyone could give me, and explain how to use, the code for saving basic data to a file. I want to save basic text and numbers and be able to use these files by the program as a data base for data inputed by the program. If anyone has any idea how to do his taht would help. Thanks
 
Hello benb, there's several ways but here's an example that uses the most basic form which is ANSI standard C/C++ - this code should compile on any platform (eg, Mac, Windows, Unix, etc) with a C++ compiler.[tt]

#include <stdlib.h>
#include <stdio.h>

void main (void)
{
FILE* f = fopen(&quot;testtext.txt&quot;,&quot;wt+&quot;);
if (f)
{
fputs(&quot;Hello World!&quot;,f);
fflush(f);
fclose(f);
}

double d = 3.141592653589;

f = fopen(&quot;testbin.dat&quot;,&quot;wb+&quot;);
if (f)
{
fwrite(&d,sizeof(d),1,f);
fflush(f);
fclose(f);
}
}
[/tt]

The above program first creates a FILE pointer called 'f'. It then opens the file called 'testtext.txt' in text mode (it creates the file if it doesn't exist first!). It writes the string 'Hello World!' to the file then flushes and closes the file.
Then, the same FILE pointer is used to create a second file called 'testbin.dat' - a binary file. We create a simple data type (in this case a double 'd') and write it to the file using the ANSI function fwrite(). We then flush and close it.
In both cases we ensure that the file pointer returned from fopen() is not NULL before attempting to write data.

If you run this program you should find it creates the two files in the project folder. You can open them up with WordPad or whatever to examine the contents.

There are many other file I/O functions and methods available to you - these are the basic things and a very easy start for you. Read up on MSDN about all the other functionsonce you've had a play around with these.

Incidentally, if you fancy having a go at reading the data back in, it is more or less the reversal of writing data. You use fgets() for text strings and fread() for binary data.

[rockband]
tellis.gif

[sup]programmer (prog'ram'er), n A hot-headed, anorak wearing, pimple-faced computer geek.[/sup]​
 
ben, here's a second program that reads the data back in and prints the values out to screen:
[tt]
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void main (void)
{
char buffer[1000] = &quot;&quot;;
unsigned bytesRead = 0;
FILE* f = fopen(&quot;testtext.txt&quot;,&quot;rt&quot;);
if (f)
{
fgets(buffer,1000,f);
fclose(f);
}

double d = 0.0;

f = fopen(&quot;testbin.dat&quot;,&quot;rb&quot;);
if (f)
{
bytesRead = fread(&d,sizeof(d),1,f);
fclose(f);
}

printf(&quot;Text Input from 'testtext.txt' is: %s\n&quot;,buffer);
printf(&quot;Value Input from 'testbin.dat' is: %f\n&quot;,d);
}
[/tt]

Notice the 'modes' used to open the files - when writing data I used &quot;wb+&quot; and &quot;wt+&quot; - when reading from the files I used &quot;rt&quot; and &quot;rb&quot;. There are several combinations of modes depending on what you want to do with the file - for example, there are modes for reading, writing, reading and writing, appending, etc.
Also, it's always a good habbit to get into using fflush() after a write operation. If you are both reading and writing to the same file then use fflush() between each read/write operation.

You can store and retrieve more complex data by using structures/classes for storage. For example:
[tt]
struct MyData
{
double d;
int i;
float f;
short s;
};

// declare a MyData object...
MyData someData;

// initialize this structure's values here...

// open a file and write the data using fwrite here:
fwrite(&someData,sizeof(someData),1,f);[/tt]


Have fun!! [wavey]
tellis.gif

[sup]programmer (prog'ram'er), n A hot-headed, anorak wearing, pimple-faced computer geek.[/sup]​
 
Thank you for your help on this? Heres my specific problem, I am creating a program that creates database of weapons for a RPG im working on. Right now im stuck on debugging the program, but thatsanother matter. The program i have so far asks for a few characoristics about these weapons, in the inputdata function, shows them in the outputdata function. But does nothing in the savedata function. I am a newbie so the more explaining hte better. In this save data function i want the class weapon & wp to be saved and the variable itemcount (which counts how many items are in the database, this variable could just be set everytime by counting how many weapons are in the database). If you would like the code i could send it to you via this forum or email. thanks for you help

Ben

also i am using mac os x but an old system 9 compilor is thats makes a difference... its called codewarrior.
 
ok Ben, i have an old copy of CodeWarrior for Mac (but not OS X) and, if you're using C/C++ then let's stick to ANSI for the time being.

I'm assuming you've declared a class like this:[tt]

class MyClass
{
public:
// construction/destruction here...

// member functions here...

// member variables here...
};[/tt]

You could save the data for an object of type class MyClass using the methods I already indicated like so:[tt]

bool SaveData(const MyClass& data)
{
auto FILE* f = fopen(&quot;thedata.dat&quot;,&quot;wb+&quot;);
if (!f) return (false);
fwrite(&data,sizeof(MyClass),1,f);
fflush(f);
fclose(f);
return (true);
}[/tt]

This function will write the member variables of an an object of type MyClass to a file called 'thedata.dat' - obviously, substitute the class and file names for your specific names.
There are a couple of ways to keep count of the number of objects stored in the file. You could specifically &quot;save&quot; this number at the head of the file (ie. you write the number first then append the object data) OR... you could simply forget about the number and then when you need to read the data back in, you could get the file size and see how many times sizeof(MyClass) divides into it!

To read the data back in you could use a function like this:[tt]

bool ReadData(MyClass& data)
{
auto FILE* f = fopen(&quot;thedata.dat&quot;,&quot;rb&quot;);
if (!f) return (false);
auto unsigned bytesRead=0;
bytesRead=fread(&data,sizeof(MyClass),1,f);
fclose(f);
if (bytesRead!=sizeof(MyClass) return (false);
return true;
}[/tt]

If you want to write/read several objects (for example, if you have an array of objects of type MyClass) then you can stick a loop around the fwrite() and fread() operations to write/read each object of the array in succession.

If you have an existing data file and you want to add (append) another object on the end of the file you would use one of the 'appending' modes to open the file, eg:[tt]

FILE* f = fopen(&quot;filename&quot;,&quot;ab+&quot;);[/tt]

There are several other I/O functions that you will find helpful when dealing with files. Each file has what is called a file marker (ie. the read/write position in the file itself). It also has an EOF (end-of-file) marker. The EOF marker is a bit like a NULL terminator of a c-style string! There are a few functions for getting and setting the file marker:[tt]

ftell(); // <- gets the current position of the marker
fseek(); // <- sets the current position of the marker[/tt]

You could move the file marker to the beginning of the file like this:[tt]

fseek(f,0,SEEK_SET);[/tt]

where 'f' is the name of your FILE* - you can set it to the end of the file like this:[tt]

fseek(f,0,SEEK_END);[/tt]

and get the current position like this:
[tt]
fseek(f,0,SEEK_CUR);[/tt]

You can move it 12 bytes from the beginning like this:[tt]

fseek(f,12,SEEK_SET);[/tt]

or... 12 bytes before the end of file like this:
[tt]
fseek(f,-12,SEEK_END);[/tt]

Therefore, you can use these functions to get the actual length of the file (in bytes) like this:[tt]

fseek(f,0,SEEK_END); // move to EOF
unsigned length = ftell(f);[/tt]

Now, say you have a data file which has 8 records of type MyClass written to it and you need to update only one of them, there are two ways you can do this:
You can either create an array to hold all 8 objects and suck them all up from the file into the array then do the change as necessary and then write them all back (the long way!) OR.... you can open the file using &quot;rb+&quot; mode and fread() each object in at a time until you find the record you need to change, make the change to the object, get the current position using ftell(), set the read/write position to the current position minus sizeof(MyClass) by using the fseek() function and then fwrite() the updated object to disk.

All this file reading/writing stuff is real easy once you get your head around it. Try messing around with the basic examples I gave you. If you're using a newer version CodeWarrior then you may need to change the #include header names to the newer versions but everything should still work fine.

If you want to e-mail me your source code then feel free to do so at: nick@qed-online.com

tellis.gif

[sup]programmer (prog'ram'er), n A hot-headed, anorak wearing, pimple-faced computer geek.[/sup]​
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top