#1
  1. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Posts
    29
    Rep Power
    0

    Saving And Loading Varibles


    okay here is my problem - i am making a text based game - it's going to take awhile so i want it to have a save option - and if they come back then can just read the varibles from a file that it saves too

    such as

    int main()
    {
    sting name;

    cout <<"What is your name";
    cin >>name

    }

    then when they come back it can remeber the name becasue the varible is saved to a file (.txt of another file like that) Thank you if anyone can help me..

    ~Justin~
  2. #2
  3. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Posts
    29
    Rep Power
    0
    also return(0) and etc... i'm not going to spend my time right now putting it - but you get the picture of what i want...
  4. #3
  5. pogremar
    Devshed Novice (500 - 999 posts)

    Join Date
    Jul 2003
    Location
    At Work
    Posts
    958
    Rep Power
    13
    I'll make you a save function and a read function. You can pass as many variables as you like. you can even pass it a struct or class pointer if you like(if you have lots of stuff to save, i recomend that)

    first, the save function. is gonna be stored in the file like this:

    john doe
    89

    Code:
    void save( char * name, int energy){
    
    FILE *fp; // create a file pointer
    
    
    if((fp = fopen("c:\\foo.txt", "w")) == NULL){ // open file for writing. if your're using linux, subtitute the file  path
    printf("\n\nERROR: could not open file. \n");
    return;
    }
    
    fprintf(fp, "%s \n", name); // this puts the   string pointed to by name to the file. check how the function is fprintf()  not printf()
    
    fprintf(fp, " %d \n", energy); // this puts the interget var
    
    fclose(fp);// this closes the file
    
    //now, check the file  to see if it worked. 
    
    }
    I'll post the reading function in a little bit. that one is a little more difficult.
  6. #4
  7. pogremar
    Devshed Novice (500 - 999 posts)

    Join Date
    Jul 2003
    Location
    At Work
    Posts
    958
    Rep Power
    13
    The function up top works, but I took the liberty to write you a little program that will read and write stuff to file. Sorry if the way I'm explaying it is too simple, I'm just a fan of giving and getting thorough explanations for every thing.

    You should copy this code, compile it and run it.
    At the beginning, it will look for a file called c:\foo.txt. If it doens't find the file, it will ask you to input some text and it will create a new file with the text you entered previously( the files path is c:\foo.txt). The next time you run the program, it will read that file and display the text that you entered.


    Code:
    
    #include <stdio.h>
    #include <string.h>
    
    // This structure will hold the variables that
    // you need to save
    struct tagSAVE
    {
    char name[50];
    char level[50];
    char boss[50];
    };
    
    
    ///////////////////////////////////////
    // PROTOTYPES
    ///////////////////////////////////////
    bool read_save(tagSAVE &);
    bool save(tagSAVE &);
    
    
    
    
    ///////////////////////////////////////
    // FUCTIONS
    ///////////////////////////////////////
    
    // #####################################################
    // main function
    
    int main(){
    
    	// instance of the save structure
    	tagSAVE sav; 
    
    	// Clear the structure because if probably
    	// has garbage inside
    	memset(&sav,0,sizeof(tagSAVE)); 
    
    	// See if there is a file already in place,
    	// if not, then ask for inputs.
    	if(read_save(sav)){ // the functions return true if 
    						// there is a file.
    
    		printf("> file found. I has these variables:\n");
    
    		printf("%s\n", sav.name);
    		printf("%s\n", sav.level);
    		printf("%s\n", sav.boss);
    
    		printf("\n");
    
    	}// end if
    
    	else{ // the functioned read_save returned false
    		 // meaning there was no file.
    
    		//Get the contents to put in the file
    		printf("enter name: ");
    		gets(sav.name);
    
    		printf("enter level: ");
    		gets(sav.level);
    
    		printf("enter boss name: ");
    		gets(sav.boss);
    
    
    		// save the contents you just got
    		if(save(sav)) // if it saved, it will return true.
    		printf("\n>>>Saved successfully! \n\n");
    
    		else
    		printf("ERROR: Could not save to file.\n\n");
    
    	} // end else
    
    	return 0;
    } // end main
    
    
    
    
    // ######################################################
    // READ_SAVE // THIS FUNCTION READS THE FILE CONTENTS
    
    //Now this is the function that reads the file.
    // Pass it a struct and it will fill it up with the variables.
    //I preffer classes but they are too long to write here.
    
    bool read_save(tagSAVE & sav){
    
    FILE *fp;				// file pointer, always used when messing with files
    int i = 0;				// general purpose
    char line[50]={0};		// this array will hold the currenlt line been scanned
    char variables[3][50];	// this will hold the variables while reading
    						// the 3 is the amount of variables(name, level, boss = 3)
    						// 50 is their lengths name[50]
    
    	// open file
    	if((fp = fopen("c:\\foo.txt", "r")) == NULL){
    		printf(">Didn't find foo.txt\n");
    
    		// If the file didn't open(probably there is no file)
    		// return bad.
    		return false;
    	}
    
    
    	// if you got to this point, the file was read successfully
    	while(fgets(line, 50, fp)){ // fgets() gets contents line by line
    								// param 1 = char array, param 2 =
    								// maximun # of bytes, param 3 = file pointer 
    
        // for each iteration copy the contents of the line to a variable
    	strcpy(variables[i], line);
    
    	// increase this so that we could point to our next variable
    	i++;
    	}
    
    
    	// after the while loop is finished, copy the contents to the struct 
    	strcpy(sav.name,variables[0]);
    	strcpy(sav.level,variables[1]);
    	strcpy(sav.boss,variables[2]);
    
    // don't forget to close the file
    fclose(fp);
    
    // return good
    return true;
    }
    
    
    
    
    
    // #######################################################################
    // save function
    // #######################################################################
    bool save( tagSAVE & sav){
    
    // create a file pointer
    FILE *fp; 
    
    // open file for writing. if your're using linux, subtitute the file  path
    if((fp = fopen("c:\\foo.txt", "w")) == NULL){
    
    printf("\n\nERROR: could not open file. \n"); 
    
    // if you could open the file, you either don't have write permission or
    // there was a major error. If this happens, you can't really do anything.
    return false;
    }
    
    // This puts the string pointed to by name to the previously opened file.
    // check how the function is fprintf(), not printf()
    fprintf(fp, "%s\n", sav.name); 
    
    // put the other variable
    fprintf(fp, "%s\n", sav.level); 
    
    // we can put lots of info if we wanted
    fprintf(fp, "%s\n", sav.boss);
    
    // don't forget to close the file
    fclose(fp);
    
    // return good.
    return true;
    
    }
    :) Hope I was of help
  8. #5
  9. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Posts
    29
    Rep Power
    0
    wow - thanks dude - you where a help
  10. #6
  11. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Posts
    29
    Rep Power
    0
    so like:
    sav.boss);
    say i have HP it would be

    sav.HP);

    and also do i put that EVERYTIME i want it to save?
  12. #7
  13. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Posts
    29
    Rep Power
    0
    wait i'm stupid:
    void save( string name, int energy){
    // say there in a sting is that right?
    FILE *fp; // create a file pointer

    // i can change foo.txt to savefile.txt or something?
    if((fp = fopen("c:\\foo.txt", "w")) == NULL){ // open file for writing. if your're using linux, subtitute the file path
    printf("\n\nERROR: could not open file. \n");
    return;
    }

    fprintf(fp, "%s \n", name); // this puts the string pointed to by name to the file. check how the function is fprintf() not printf()

    fprintf(fp, " %d \n", energy); // this puts the interget var

    fclose(fp);// this closes the file

    //now, check the file to see if it worked.
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Location
    NY
    Posts
    18
    Rep Power
    0
    You could also use the following code to save and load your data. The nice thing about using the following method is that you are not limitted to a specific structure. The downside is that you must make sure that your structure does not contain pointers since the pointer will be saved and not the data being pointed to. Also, if you are using c++, you can save the entire class structure by using the this pointer in place of the address of the structure.

    Happy coding,
    messorian

    Code:
    #include <memory.h>
    #include <string.h>
    #include <stdio.h>
    
    struct Player {
    	char name[50];
    	int age;
    	char sex;
    };
    
    // forward declares for functions
    void save(char* file, void* item, int size);
    void load(char* file, void* item, int size);
    
    int main(int argc, char* argv[]) {
    	// declare and initialize a player object
    	Player pl;
    	pl.age = 25;
    	strcpy(pl.name, "Bob");
    	pl.sex = 'M';
    	
    	// save the player structure
    	save("c:\\player.dat", &pl, sizeof(Player));
    	// clear the player structure for testing purposes
    	memset(&pl, 0, sizeof(pl));
    	
    	// load the data back into the player structure
    	load("c:\\player.dat", &pl, sizeof(Player));
    
    	return 0;
    }
    
    // saves the structure or class into <file>
    void save(char* file, void* item, int size) {
    	FILE *fp;
    
    	// open a file for binary writing
    	fp = fopen(file, "wb");
    
    	// validate the file pointer
    	if (fp == NULL) {
    		printf("Could not open %s for writing.\n", file);
    		return;
    	}
    
    	// write the structure or class to the file
    	fwrite(item, size, 1, fp);
    
    	// be a good citizen and clean up after yourself
    	fclose(fp);
    
    	return;
    }
    
    // reads the structure from  <file>
    void load(char* file, void* item, int size) {
    	FILE *fp;
    
    	// open the file for binary writing
    	fp = fopen(file, "rb");
    
    	// validate the file pointer
    	if(fp == NULL) {
    		printf("Could not open file %s for reading.", file);
    		return;
    	}
    	
    	// read the data back into the structure
    	fread(item, size, 1, fp);
    
    	// make sure to clean up after yourself
    	fclose(fp);
    
    	return;
    
    }
  16. #9
  17. pogremar
    Devshed Novice (500 - 999 posts)

    Join Date
    Jul 2003
    Location
    At Work
    Posts
    958
    Rep Power
    13
    >> open the file for binary writing
    in the load function, messorian meant reading.

    Messorian is writing to a file in binary mode. If you're making a save file, you should probably do it this way in order to prevent the player from cheeting by changing the contents of the text file.

    In answer to your questions above, if for some reason you decide to still go with the text file option(maybe you wanna make a configuration text file)

    >> void save( string name, int energy){
    >> // say there in a sting is that right?
    No. In C, there is not a variable called string(unless you define a struct named such). To make a string you would do:
    char string_name[50];
    Here, you're making a string named "string_name" that can hold 50 chars. You don't put stuff in a string like this:
    string_name = "something";
    You have to use a function called strcpy() like so:
    strcpy(string_name, "the text you want to copy");

    See the codes in the previous posts so you can see how this comes into effect.

    >>> // i can change foo.txt to savefile.txt or something?
    sure you can. Just remember, in C, the \ character is the "scape character" meaning that the following character after the \ will be interpreted in a special way. For example, if you had something like this c:\test\noxious C would think that you mean c:(\t, special character which equals tab)est (\n, which means new line)oxious.

    Visually, ti looks like this
    c:[tab]est[new line]
    oxious

    So, if you wanna make a string like this c:\test\saves\foo.txt the string should look like this
    c:\\test\\saves\\foo.txt
    Since the \ is the scape character, if you wanna put a literal backslash you should scape it. Remeber that as we have all ran into that kind of problem.

    Moving on. You can't pass a whole string to a function because that would be inefficient. Imagine if you had a string like this:
    char big_string[1,000,000];
    You probably wouldn't have string so big, but if you did passing that string to a functions would be an immense performance hit. What you want to do ( and the right solution) is to pass the function a pointer to the string. A pointer is a variable that holds the address in memory of the string. Basically, you wanna say "look function, here is the address for my string. Whatever you do to this string, send the changes to that address".

    Let's say we're calling a function from our main function:

    Code:
    #include <stdio.h> // for printf
    #include <string.h> // for string functions
    
    // prototype
    void print_stuff(char *); // see, the function takes a pointer as an argument
    
    int main(){
    
    // make array that will hold the message
    char happy_array[100];
    
    // put something in the array
    strcpy(happy_array, "I am so happy, the world is beautiful.");
    
    // call the function
    print_stuff(happy_array);
    
    // other lines of code if you want
    
    return 0;
    
    }
    
    void print_stuff(char * stuff){
    
    printf("%s \n", stuff);
    
    }


    >>>say i have HP it would be

    sav.HP);
    Yeah. Make sure you put that variable into the struct, like so:

    struct tagSAVE
    {
    char name[50];
    char level[50];
    char boss[50];
    int HP;
    };

    to put something into that variable do
    sav.HP = 9;

    If you're saving to a text file, putting the integer is easy, but reading back is a little more difficult because when is read back it is interpreted as a char. I had a question on how to read back an interger in a text file and interpret it as an int instead of a char. A user named scorpion4ever gave me a very thorough explanation. see it here:
    http://forums.devshed.com/t68843/s.html

    :cool: Laters
  18. #10
  19. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Posts
    29
    Rep Power
    0
    wait.......is all this script you gave me made for C? I needed it for C++.......
  20. #11
  21. pogremar
    Devshed Novice (500 - 999 posts)

    Join Date
    Jul 2003
    Location
    At Work
    Posts
    958
    Rep Power
    13
    Does it need to be specifically c++?
    You do know that you can mixed them up in the same source file. C++ is just C with object oriented functionality. That functionality is often very good as classes help you make certain things more error free, however, sometimes that functionality is overkill in my opinion.
  22. #12
  23. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Posts
    29
    Rep Power
    0
    i don't know - i'm new at c++ - so i didn't know - but thanks for your help

IMN logo majestic logo threadwatch logo seochat tools logo