How to write a undertemined size array to a txt file?

Started by
15 comments, last by wintertime 10 years, 6 months ago
Which part specifically is giving you trouble? Can you print the contents of a text file to the screen? Can you read values from std::cin into variables? Is it a particular type of variable that is giving you trouble?

What have you tried?
Advertisement

Which part specifically is giving you trouble? Can you print the contents of a text file to the screen? Can you read values from std::cin into variables? Is it a particular type of variable that is giving you trouble?

What have you tried?

well i'm using the "standard" way of I/O files, like this


string line;
    ifstream myfile("data\\checkpoint01.txt");

    if(myfile.is_open()){
        while(myfile.good()){

            getline(myfile,line);
            cout << line << endl;
                            }
        myfile.close();

but this clearly doesn't fit for me because it writes everything in the file, and i want it to grab the first line, assign it to a variable, second line same thing, grab the next 4 lines and assign it to an array and so on

The first thing you should do is think about how you want to structure your save file. XML might be a bit of an overkill for a text RPG, especially if the programmer is new to the language. I suggest doing an "INI" approach, where you tag different sections of your file using square brackets. Example:


[playernames]
John McCarter
The Dark One
Margret Baxter

[weapons]
The Skull crusher
Frilly Underwear (Pink)
Baguette

The tags are there so you can detect them later in the code. Your approach is pretty solid so far, but you have to expand it to something like this:


#include <iostream>
#include <string>
#include <vector>
#include <fstream>

int main()
{

    std::vector<std::string> playerNames;
    std::vector<std::string> weapons;

    std::string line;
    int state = 0; // state 1 is playerNames, state 2 is weapons, and so on

    std::ifstream myfile("data/checkpoint01.txt");
    if(myfile.is_open()){
        while(myfile.good()){

            std::getline(myfile,line);

            // switch states
            if( line[0] == '[' ){
                if( line.compare("[playernames]") == 0 ) state = 1;
                if( line.compare("[weapons]") == 0 ) state = 2;

                // skip to next line
                std::getline(myfile,line);
            }

            switch(state){

                // player names
                case 1 :
                    if( line.size() > 0 ) playerNames.push_back( line );
                    break;

                // weapons
                case 2 :
                    if( line.size() > 0 ) weapons.push_back( line );
                    break;

                default: break;
            }

        }
        myfile.close();
    }else
        std::cout << "error opening file" << std::endl;

    // now print data to the screen
    std::cout << "player names:" << std::endl;
    for( std::vector<std::string>::iterator it = playerNames.begin(); it != playerNames.end(); ++it )
        std::cout << *it << std::endl;

    std::cout << std::endl << "weapons:" << std::endl;
    for( std::vector<std::string>::iterator it = weapons.begin(); it != weapons.end(); ++it )
        std::cout << *it << std::endl;

    return 0;
}

Note to the more experienced: I know you could refactor this into a class with read/write methods, and should make separate classes for players, weapons etc. etc. and should probably define constants for states instead of numbers, but that's not the point.

"I would try to find halo source code by bungie best fps engine ever created, u see why call of duty loses speed due to its detail." -- GettingNifty

well i seem to understand that code, but how do i assign those values into my variables? and how do i do it if it's, for example, an array?

because my method of writing to the file atm is 1 line per value, so if i have like

playerItem[1][0] = 0

playerItem[1][1] = 2

playerItem[1][2] = 3

it writes like

o

2

3


but how do i assign those values into my variables? and how do i do it if it's, for example, an array?

That's basically what my code is demonstrating. It's reading an arbitrary amount of data from a text file and pushing them into an std::vector<T> (remember, that's an "array").

Maybe I'm not quite understanding what you're asking. Could you elaborate more? What arrays are you using now? Are you using std::vector<T>? Please post your declaration of playerItem[] again so we're on the same page.

Can you also provide the code you're using to write to the file?

"I would try to find halo source code by bungie best fps engine ever created, u see why call of duty loses speed due to its detail." -- GettingNifty

hm no i stil haven't used vectors for anything, up until now i can succesfully write all the variables and array to the file, and trying to see how to read them back.

(looking again to the vectors i understand what you're doing, although i wanna assign those values into my own variables, maybe your code can do that and i'm just too noob to realise)

this is my writing code:


ofstream myfile("data\\checkpoint01.txt", ios::trunc);
         if(myfile.is_open()){
             myfile << playerInfo[0] << endl;
             myfile << playerLocation << endl;
             myfile << roleNr << endl;
             myfile << role << endl;
             myfile << playerName << endl;
             myfile << gold << endl;
             myfile << playerHealth << endl;
             myfile << playerStrength << endl;
             myfile << playerAgilty << endl;
             myfile << playerEndurance << endl;
             myfile << playerMaxHealth << endl;
             myfile << playerItemCount << endl;
             for(int i=0; i<playerItemCount; ++i){
                 for(int j=0; j<3; ++j){
                    myfile << playerItems[i][j] << endl;
                                        }
                                                }
             for(int i=0; i<3; ++i){
                for(int j=0; j<3; ++j){
                    if(playerEquippedItems[i][0]!=0){
                        myfile << playerEquippedItems[i][j] << endl;
                                                    }
                                        }
                                    }
             myfile << questUpdate1 << endl;
             myfile.close();

                        }

          else cout << "Unable to open quest file.\n";

i hope this answers to all that you asked

A better way is you just check how big the file is(move file pointer to end, read it, move it to beginning), allocate memory(vector::resize or new unsigned char[]), read the whole file in a single call into that memory, close the file. Mapping the file directly into memory is even better for larger files but needs OS-specific API calls like CreateFile, GetFileSize, CreateFileMapping, MapViewOfFile, UnmapViewOfFile and CloseHandle on Windows, mmap on Unix.

Then you can use normal array indexing to check the data und pick what you need. Not only is that easier, it can also be faster to not do so many read calls.

When writing the file you can do it in similar way and put everything into a vector first and write it in one call.

This topic is closed to new replies.

Advertisement