I have an array, how would I save it to a file? All I need is the ability to save it from the program and load it later.
I am using C++, so I would prefer a C++ function to do this.:P
edit: the header file is #include <fstream.h>
this uses link list instead of arrays but its the same idea.
just change nd->ClientObject.Set_username( namer);
array[index]= namer.
you mite be adlbe to do this too.
inData >> array[index];
1 | ///and load from file |
2 | void ClientDatabase::load( ) |
3 | { |
4 | ifstream inData; |
5 | inData.open("Clients.txt" ); |
6 | |
7 | char trash ; |
8 | int num = 0; |
9 | int num2 = 0; |
10 | string namer ; |
11 | inData >> num; |
12 | inData >> trash; |
13 | |
14 | while( numItems2 < num) |
15 | { |
16 | |
17 | ClientConfig* nd; |
18 | nd = new ClientConfig; |
19 | inData >> namer; |
20 | nd->ClientObject.Set_username( namer); |
21 | |
22 | inData >> namer; |
23 | nd->ClientObject.Set_password(namer); |
24 | |
25 | inData >> namer; |
26 | nd->ClientObject.CharacterObject.Set_name(namer); |
27 | //inData >> trash; |
28 | |
29 | |
30 | inData >> num2; |
31 | if (num2 == 1) |
32 | { |
33 | nd->ClientObject.CharacterObject.Set_race("namakan"); |
34 | } |
35 | inData >> trash; |
36 | |
37 | |
38 | |
39 | inData >> num2; |
40 | if (num2== 1) |
41 | { |
42 | nd->ClientObject.CharacterObject.Set_sex(male); |
43 | } |
44 | else if(num2== 2) |
45 | { |
46 | nd->ClientObject.CharacterObject.Set_sex(female); |
47 | } |
48 | inData >> trash; |
49 | |
50 | |
51 | inData >> num2; |
52 | nd->ClientObject.CharacterObject.Set_X(num2); |
53 | inData >> trash; |
54 | //textprintf_centre(screen, font, 40, 200, makecol(255, 255, 255),"FPS:%d", num2); |
55 | |
56 | inData >> num2; |
57 | nd->ClientObject.CharacterObject.Set_Y(num2); |
58 | inData >> trash; |
59 | |
60 | inData >> num2; |
61 | nd->ClientObject.CharacterObject.Set_W(num2); |
62 | inData >> trash; |
63 | |
64 | inData >> num2; |
65 | nd->ClientObject.CharacterObject.Set_H(num2); |
66 | inData >> trash; |
67 | |
68 | inData >> num2; |
69 | nd->ClientObject.CharacterObject.Set_layer(num2); |
70 | inData >> trash; |
71 | |
72 | inData >> num2; |
73 | nd->ClientObject.CharacterObject.Set_source_X(num2); |
74 | inData >> trash; |
75 | |
76 | inData >> num2; |
77 | nd->ClientObject.CharacterObject.Set_source_Y(num2); |
78 | inData >> trash; |
79 | |
80 | inData >> num2; |
81 | if (num2== 0) |
82 | { |
83 | nd->ClientObject.CharacterObject.Set_collision(false); |
84 | } |
85 | else if (num2== 1) |
86 | { |
87 | nd->ClientObject.CharacterObject.Set_collision(true); |
88 | } |
89 | inData >> trash; |
90 | |
91 | |
92 | inData >> num2; |
93 | nd->ClientObject.CharacterObject.Set_frame(num2); |
94 | inData >> trash; |
95 | |
96 | |
97 | |
98 | inData >> num2; |
99 | nd->ClientObject.CharacterObject.Set_direction(num2); |
100 | inData >> trash; |
101 | |
102 | |
103 | inData >> num2; |
104 | nd->ClientObject.CharacterObject.Set_sourcebitmap(num2); |
105 | inData >> trash; |
106 | |
107 | |
108 | inData >> num2; |
109 | if (num2== 1) |
110 | { |
111 | //nd->ClientObject.CharacterObject.Set_destbitmap(); |
112 | } |
113 | inData >> trash; |
114 | |
115 | inData >> num2; |
116 | //netId ++; |
117 | nd->ClientObject.CharacterObject.Set_id(1); |
118 | inData >> trash; |
119 | |
120 | inData >> num2; |
121 | nd->ClientObject.CharacterObject.Set_inarea(num2); |
122 | inData >> trash; |
123 | |
124 | inData >> num2; |
125 | nd->ClientObject.CharacterObject.Set_socketid(num2); |
126 | |
127 | nd->ClientObject.CharacterObject.Set_destx(nd->ClientObject.CharacterObject.Get_X()); |
128 | nd->ClientObject.CharacterObject.Set_desty(nd->ClientObject.CharacterObject.Get_Y()); |
129 | nd->ClientObject.CharacterObject.toString(); |
130 | //need to load stats as well |
131 | nd->SetNext( head ); |
132 | head = nd; |
133 | numItems2++; |
134 | |
135 | } |
136 | |
137 | inData.close(); |
138 | |
139 | |
140 | } |
141 | |
142 | |
143 | |
144 | |
145 | |
146 | |
147 | |
148 | |
149 | |
150 | |
151 | ///and save to file |
152 | void ClientDatabase::save( ) |
153 | { |
154 | ClientConfig* nd; |
155 | nd = head; |
156 | |
157 | ofstream outData; |
158 | outData.open("Clients.txt" ); |
159 | |
160 | outData << numItems2; |
161 | outData << ","; |
162 | outData << endl; |
163 | while( nd != NULL ) |
164 | { |
165 | outData << nd->ClientObject.Get_username(); |
166 | outData << endl; |
167 | outData << nd->ClientObject.Get_password(); |
168 | outData << endl; |
169 | outData << nd->ClientObject.CharacterObject.Get_name(); |
170 | outData << endl; |
171 | outData << 1;//nd->ClientObject.CharacterObject.Get_race(); |
172 | outData << ","; |
173 | outData << 1;//nd->ClientObject.CharacterObject.Get_sex(); |
174 | outData << ","; |
175 | outData << nd->ClientObject.CharacterObject.Get_X(); |
176 | outData << ","; |
177 | outData << nd->ClientObject.CharacterObject.Get_Y(); |
178 | outData << ","; |
179 | outData << nd->ClientObject.CharacterObject.Get_W(); |
180 | outData << ","; |
181 | outData << nd->ClientObject.CharacterObject.Get_H(); |
182 | outData << ","; |
183 | outData << nd->ClientObject.CharacterObject.Get_layer(); |
184 | outData << ","; |
185 | outData << nd->ClientObject.CharacterObject.Get_source_X(); |
186 | outData << ","; |
187 | outData << nd->ClientObject.CharacterObject.Get_source_Y(); |
188 | outData << ","; |
189 | outData << 0; //nd->ClientObject.CharacterObject.Is_in_collision(); |
190 | outData << ","; |
191 | outData << nd->ClientObject.CharacterObject.Get_frame(); |
192 | outData << ","; |
193 | outData << 1 ;//nd->ClientObject.CharacterObject.Get_direction() |
194 | outData << ","; |
195 | outData << nd->ClientObject.CharacterObject.Get_sourcebitmap(); |
196 | outData << ","; |
197 | outData << 2;//nd->ClientObject.CharacterObject.Get_destbitmap(); |
198 | outData << ","; |
199 | outData << nd->ClientObject.CharacterObject.Get_id(); |
200 | outData << ","; |
201 | outData << nd->ClientObject.CharacterObject.Get_inarea(); |
202 | outData << ","; |
203 | outData << nd->ClientObject.CharacterObject.Get_socketid(); |
204 | //need to save stats as well |
205 | outData << endl; |
206 | |
207 | |
208 | |
209 | |
210 | nd = nd->GetNext( ); |
211 | |
212 | } |
213 | |
214 | |
215 | outData.close(); |
216 | |
217 | } |
edit: this is what the file looks like
7,
k
password
kay-anne
1,1,2060,1590,32,32,2,0,0,0,1,1,4,2,3,1,-1
piccolo
password
KingPiccolo
1,1,2095,1550,32,32,2,0,0,0,1,1,4,2,2,1,-1
kidbuu
password
kidbuu
1,1,2060,1590,32,32,2,0,0,0,1,1,4,2,1,1,-1
sun
password
smasher
1,1,2080,1585,32,32,2,0,0,0,1,1,4,2,1,1,-1
ben
password
bigben
1,1,2080,1585,32,32,2,0,0,0,1,1,4,2,1,1,-1
cell
password
Cell
1,1,2080,1585,32,32,2,0,0,0,1,1,4,2,1,1,-1
j
password
if it is unclear please tell me.
If you can afford the dependency on Boost, it has a very neat serialization module. You can read up on it here. It works very nicely with STL, so if your array is in fact stored in a std::vector or a std::list, saving and loading the entire thing requires very little effort.
piccolo: I certainly hope you didn't post peoples' passwords in that list!
no those are test user accounts the password for all those users is password. but i disabled password input so it will be essayer to test every thing.
i am recoding my character list as a unit list so i can read in many different objects from the same file.
That's kind of a security risk, posting passwords in plain text... md5 them before you save them to the file?
yeah i know but this is still in developing faze so its a lot easer to debug when you can read whats in the text file.
Durnus,
I'm not sure if it'll it'll work with arrays, but using ofstream.write (google on fstream) you can output a class:
#include <fstream> ... ofStream fout("someFileName", ios::binary); fout.write((char*) &class, sizeof class); fout.close(); ... ifstream fin("someFileName", ios::binary); fin.read((char*)&class, sizeof class); fin.close(); ...
Durnus, could you give a little more detail for clarification?
As piccolo's example showed, the first line of text you output states "how many lines/records will follow", and you would loop that many times when you decide to read back the data.
Something like:
1 | #include <fstream> |
2 | |
3 | struct userData |
4 | { |
5 | public: |
6 | string f_name; |
7 | string m_name; |
8 | string l_name; |
9 | string birthday; // YYMMDD format |
10 | int number_of_teeth; |
11 | }; |
12 | |
13 | int main() |
14 | { |
15 | userData newData; |
16 | vector<userData> myArray; |
17 | int numRecords; |
18 | |
19 | ifstream fin; |
20 | fin.open("yourfile.txt"); |
21 | fin >> numRecords; |
22 | for (int curRecord = 0; curRecord < numRecords; curRecord++) |
23 | { |
24 | fin >> newData.f_name >> newData.m_name >> newData.l_name >> newData.birthday >> newData.number_of_teeth; |
25 | myArray.push_back(newData); |
26 | newData.clear(); |
27 | } |
28 | |
29 | // Your own code here to deal with the "myArray" vector |
30 | |
31 | return 0; |
32 | } |
You would have to have "yourfile.txt" in that specific order, and prefixed with the number of records you want to read in.
Another method would be to save each record on a separate line, and consider the newline as a record-delimiter (meaning you wouldn't have to know before-hand how many records you had, but you WOULD need some sort of dynamic array to store them into: like std::vector).
I guess my question is, you have "an array" of something. Are you asking how to output to a file, or how to read in your array data from the disk after you're already saved it?
You still aren't using a database? sqlite would work perfect for you in this case.
yeah i'm am but i want to be the first mmrpg in the depot where someone can compile the code. if i put the 3rd party database that will mean in or to try my code you will have to have Oracla 10g installed. im going to make 2 versions of the game one with oracle and one with out. i did do the research and i got have a data base running on my computer. and i got it to work with c++ usint the ODB class library but ill save that for the other version of the game.
yeah i'm am but i want to be the first mmrpg in the depot where some can compile the code. if i put the 3rd party database that will mean in or to try my code you will have to have Oracla 10g installed. im going to make to version of the game one with oracle and one with out. i did do the research and i got have a data base running on my computer. and i got it to work with c++ use ODB class library but ill save that for the other version of the game.
No offense but; Did you even try to write in English?
Just use SQLite. It's "light". Just one file with the database information, and (iirc) two files to add to your project to use. No servers or services needed.
You don't add ANY files to your project to use it. Just #include the sqlite header once you have sqlite installed.
Right you are, i just checked. Just compile it and link the static library. It's also very easy to use (although I'm not that crazy about the function-pointer dependent execute function).
And there are some nice, free, sqlite "browsers" out there.
Sorry about not responding to my post, but I can't use a computer during the week.
I don't really need specific code, but just a way to write to a file (a text file or whatever) and put it back into my program.
More specifically, what I need is a function to output to a file, (I am seeing this as outData in the examples.) and a function to get data from a file. (inData?) I also need to be able to tell when a new line starts.
And yes, I have already planned to use a vector to store my array on input, and to put it into a file I will iterate through my array and print the data in array-like form.
all you need is:
or if using allegro I suggest using
pack_fopen, pack_fwrite, and pack_fread
the allegro routines can be setup to use transparent compression.
-- Offtopic: --
Don't use oracle as a db server for a game, use sqlite, or if you absolutely have to mysql (mysql is free and can be setup anywhere, oracle is not) -- as a side option there is always SQL Server, the 2005 version is free but only supports one connection at a time or something along those lines... anyway lots of web hosts will sell you access to sql server 2000/2005 for under $10/mo ... -- sorry to butt in if I'm misunderstanding.
Durnus, are you asking to open the array into a file using the Allegro library, or just "in general" using iostreams?
anyway lots of web hosts will sell you access to sql server 2000/2005 for under $10/mo
What webhosts do that? Most hosts, in most cases, if they are smart, only allow access to their SQL servers from other servers that they run. A SQL server open to the public is usually a big security issue, especially if it's a Microsoft product.
But, I do agree that sqlite is the best idea here.
But anyway, if you are planning on running an open SQL server for the release version of your game you have serious design flaws. The clients shouldn't even know about SQL (unless they use sqlite for local storage). All processing and such should be done by the server and stored server side on to private SQL storage.
I didn't say direct access -- I've actually not done it -- but my host offers it, I'm not sure HOW you access it, and the only server that has direct access to it is the web server -- I probably have to login to some web interface that lets me run DB scripts / manage my own DB's permissions -- and I'm pretty sure that the $10 is per DB... -- However my host also offers access to mysql databases... I wonder if they charge for it? probably.
Back on topic, yeah: no, the client should never have access to the database, the database should be server side -- sqlite is light, easy, and fast -- it's also file based instead of client/server based (sql server/mysql both require TCP connections, even if it's thru local host...)
mysql/sql server hosting with your game hosting is going to cost a pretty penny.
oracle is free as long as its not used for comurshell purpuses. plus using it in your games is a good why to learn it for the work place.
it's really not suited for game development though -- again it's a server database engine -- I suppose if whoever is hosting your game is also hosting an oracle server then why not? -- but it's going to be slower than SQLite, larger, and harder to work with... also Oracle seems like it's getting obscure anymore -- the only places that I've worked that use Oracle, use Orcale because they've been using it 15 to 20 years...
Durnus, are you asking to open the array into a file using the Allegro library, or just "in general" using iostreams?
Good question.
All I'm asking is to be able to write into a file and put the file into a variable.
(EDIT: ) I'm not looking to use the allegro library, I'm actually hoping to use some standard library, such as fstream.
Now I know how to write into a file, but I still don't know how to read a file into a variable. All the websites I look at aren't very clear about reading.
BTW, HardTranceFan, that is a horrible practice which should not be practiced (writing whole classes/structs to files).
Anyway, Durnus, did you read this post?
Now I know how to write into a file, but I still don't know how to read a file into a variable. All the websites I look at aren't very clear about reading.
Durnus, if you are already using fstream to write OUT to a file, you can use the same function to read it back in. (Some example code is in this same thread: http://www.allegro.cc/forums/thread/588899/633084#target )
Might I also suggest: If you've ever used "cin" or "cout" from the console for a simple "Hello World" program, you can use fstream in almost the exact same way: I usually name my "file input" and "file output" as "fin" and "fout", to match the "console (in|out)" of "(cin|cout)":
1 | #include <fstream> |
2 | #include <vector> |
3 | |
4 | int main() |
5 | { |
6 | int rows; // In your source code, declare the variables you want to "import" your |
7 | int cols; // data into. These first two types are integers, as the size of the |
8 | // map will be written as the first two values in a file |
9 | int fileInput; // This is where the data read in from the file will be temporarily stored |
10 | vector<int> theMap; // This is where the data will be stored for the rest of your |
11 | // the time you are inside your game |
12 | |
13 | ifstream fin; // I like "FIN" to signify "file input" |
14 | fin.open("your_map_file.map", ios::in); |
15 | |
16 | fin >> rows; // The first line of the map contains the number of rows |
17 | fin >> cols; // The second line of the map contains the number of columns |
18 | |
19 | for (int currentRow = 0; currentRow < rows; currentRow++) |
20 | { |
21 | for (int currentCol = 0; currentCol < cols; currentCol++) |
22 | { |
23 | fin >> fileInput; // This pulls in each bit of data (the ">>" ignores whitespace) |
24 | theMap.push_back(fileInput); // Push the data now stored in "fileInput" to your vector |
25 | } |
26 | } |
27 | |
28 | // Your "theMap" vector should now contain (rows * cols) number of entries, all |
29 | // collected from the "your_map_file.map" file |
30 | |
31 | // We are done with "fin", so close it: |
32 | fin.close(); |
33 | |
34 | ...do stuff with your map... |
35 | |
36 | return 0; |
37 | } |
I hope this helps a bit: You OUTPUT to the screen or file with "<<", like cout << "Hello, world!" and read INPUT from a keyboard (console input device) or file with ">>", like cin >> userResponse; or fin >> someDataFromFile;.
I hope this helps!
Yes, it helps, but I just need one more thing.
How does the inputting know where to stop putting the data into a variable? Does it stop when it hits a space? Does it stop when it hits a new line? Can I set what it stops at?
From what I've seen, the input function keeps on incrementing itself, and that was a question I had.
Anyway, thanks for all the help.
The basic ">>" operator stops at all whitespace, so it will read in "12345 4345 888" as three separate numbers (or strings of char, or even std::string's). It completely ignores whitespace (spaces and tabs), and newlines.
For a school project, we had been asked to read in a line of text, parse the important data, then continue to the next line, etc.
The "getline" function will stop at whitespaces (you can also tell it to stop at a certain character, like a space or even a specific character). If you have a stream (like an fstream), the parameters I've used are:
getline(fin, some_string, '\n'); to read in from "fin" input stream, save the data to the "some_string" string, and stop as soon as it sees a newline character. The third parameter is '\n' by default, so if you change it to something else, it will stop parsing "the line" when it hits that character (so if you have line-comments that start with '#', you can use that). If you leave off that third parameter, it assumes you want just to the end of the line.
Does that help?