issues saving and loading from txt file(strings w/ whitespaces)

hey guys,

I am having issues with loading the string "Dirty T-Shirt" from a text file i use to save my game with.

When I load it, it splits it up. Like (torso : Dirty, Hands : T-shirt) it should be (torso : Dirty T-shirt). I thought I heard using cin to set a string variable like this will cause issues like this. The thing is I initialize the game with the variable "Torso" set to "Dirty T-shirt". I never actually input it using cin.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
Player::Player()
     {
       wallet = 25;
       gadget = "NOTHING";
       head = "Dirty Baseball Cap";
       torso = "Dirty T-Shirt";
       pants = "Dirty Jeans";
       hands = "NOTHING";
       feet = "Old Sneakers";
       leftHand = "NOTHING";
       rightHand = "NOTHING";
       
       hasFitWatch = false;
       hasCargoPants = false;
       hasPack = true;
       hasVest = false;
       hasLPack = false;
       hasCampingKit = false;
                       
       hunger = 70;
       thirst = 70;
       energy = 70;
       health = 100;
       //bodyTemp = 98.6;
       alive = true;
       lightState = 0;          
     }
void Player::SaveGame()
{
	outputFile.open("PlayerSave.txt");
	if (outputFile.fail())
	{
		perror("PlayerSave.txt");
	}
	outputFile << wallet << endl;
	outputFile << gadget << endl;
	outputFile << head << endl;
	outputFile << torso << endl;
	outputFile << pants << endl;
	outputFile << hands << endl;
	outputFile << feet << endl;
	outputFile << leftHand << endl;
	outputFile << rightHand << endl;
	outputFile << hasFitWatch << endl;
	outputFile << hasCargoPants << endl;
	outputFile << hasPack << endl;
	outputFile << hasVest << endl;
	outputFile << hasLPack << endl;
	outputFile << hasCampingKit << endl;
	outputFile << hunger << endl;
	outputFile << thirst << endl;
	outputFile << health << endl;
	outputFile << alive << endl;
	outputFile << lightState << endl;
	outputFile << pack[0] << endl;
	outputFile << pack[1] << endl;
	outputFile << pack[2] << endl;
	outputFile << pack[3] << endl;
	outputFile << pack[4] << endl;
	outputFile << pack[5] << endl;
	outputFile << pack[6] << endl;
	outputFile << pack[7] << endl;
	outputFile << pack[8] << endl;
	outputFile << pack[9] << endl;
	outputFile << chest[0] << endl;
	outputFile << chest[1] << endl;
	outputFile << chest[2] << endl;
	outputFile << chest[3] << endl;
	outputFile << chest[4] << endl;
	outputFile << chest[5] << endl;
	outputFile << chest[6] << endl;
	outputFile << chest[7] << endl;
	outputFile << chest[8] << endl;
	outputFile << chest[9] << endl;
	outputFile << chest[10] << endl;
	outputFile << chest[11] << endl;
	outputFile << chest[12] << endl;
	outputFile << chest[13] << endl;
	outputFile << chest[14] << endl;
	outputFile.close();
}
void Player::LoadGame()
{
	inputFile.open("PlayerSave.txt");
	if (inputFile.fail())
	{
		perror("PlayerSave.txt");
	}
	inputFile >> wallet;
	inputFile >> gadget;
	inputFile >> head;
	inputFile >> torso;
	inputFile >> pants;
	inputFile >> hands;
	inputFile >> feet;
	inputFile >> leftHand;
	inputFile >> rightHand;
	inputFile >> hasFitWatch;
	inputFile >> hasCargoPants;
	inputFile >> hasPack;
	inputFile >> hasVest;
	inputFile >> hasLPack;
	inputFile >> hasCampingKit;
	inputFile >> hunger;
	inputFile >> thirst;
	inputFile >> health;
	inputFile >> alive;
	inputFile >> lightState;
	inputFile >> pack[0];
	inputFile >> pack[1];
	inputFile >> pack[2];
	inputFile >> pack[3];
	inputFile >> pack[4];
	inputFile >> pack[5];
	inputFile >> pack[6];
	inputFile >> pack[7];
	inputFile >> pack[8];
	inputFile >> pack[9];
	inputFile >> chest[0];
	inputFile >> chest[1];
	inputFile >> chest[2];
	inputFile >> chest[3];
	inputFile >> chest[4];
	inputFile >> chest[5];
	inputFile >> chest[6];
	inputFile >> chest[7];
	inputFile >> chest[8];
	inputFile >> chest[9];
	inputFile >> chest[10];
	inputFile >> chest[11];
	inputFile >> chest[12];
	inputFile >> chest[13];
	inputFile >> chest[14];
	inputFile.close();
}
////////////////////////////////////////////////////////////////////////////////
void Player::DisplayGear()
{
        //below displays in console
        //Head    [Dirty]
        //Torso   [Baseball]
        //Hands   [Dirty]
        //Legs    [Cap]
        //Feet    [T-shirt]
        //Holding [Dirty] [Jeans]
        //Gadget  [NOTHING]
        //Wallet  [$25]
	cout << endl;
	cout << "-|[GEAR]|-" << endl << endl;;
	cout << "HEAD     -[-" << head << "-]-" << endl;
	cout << "----------------------------------" << endl;
	cout << "TORSO    -[-" << torso << "-]-" << endl;
	cout << "----------------------------------" << endl;
	cout << "HANDS    -[-" << hands << "-]" << endl;
	cout << "----------------------------------" << endl;
	cout << "LEGS     -[-" << pants << "-]-" << endl;
	cout << "----------------------------------" << endl;
	cout << "FEET     -[-" << feet << "-]-" << endl;
	cout << "----------------------------------" << endl;
	//if (iteminhands == onehanded)
	cout << "HOLDING  -[-" << leftHand << "-]---[-" << rightHand << "-]-" << endl;
	cout << "----------------------------------" << endl;
	//else if two handed
	//"HOLDING[ bothHands]
	cout << "GADGET   -[-" << gadget << "-]-" << endl;
	cout << "----------------------------------" << endl;
	cout << "WALLET   -[-$ " << wallet << "-]-" << endl;
	cout << "----------------------------------" << endl;
}


Here is what is listed in the txt file i use to save

25 //// wallet
NOTHING //// gadget
Dirty Baseball Cap //// head
Dirty T-Shirt //// torso
Dirty Jeans //// legs
NOTHING //// hands
Old Sneakers //// feet
Falshlight //// lefthand
NOTHING //// righthand
0 //// hasfitwatch bool
0
1
0
0
0
55
30
100
1
2
Bottle(Full, Water) //// pack[0]
Candy //// 1
Gas Can //// 2
-Empty- //// 3
-Empty- //// 4
-Empty- //// 5
-Empty- //// 6
-Empty- //// 7
-Empty- //// 8
-Empty- //// 9
-Empty- //// chest[0]
-Empty- //// 1
-Empty- //// 2
-Empty- //// 3
-Empty- //// etc to 14
-Empty-
-Empty-
-Empty-
-Empty-
-Empty-
-Empty-
-Empty-
-Empty-
-Empty-
-Empty-

If you need to know more to help solve this issue let me know.
Last edited on
The >> operator reads one word (until it finds a whitespace character). If you want to read the whole line you can use std::getline.

http://www.cplusplus.com/reference/string/string/getline/
I believe whenever you use your current method of reading from a file, it reads the line until it hits a space (hence the splitting of your dirty tshirt).

The most effective way of reading a line from a file will be with getline().
Please see the reference for more information if needed.
http://www.cplusplus.com/reference/string/string/getline/

1
2
3
4
ifstream inputFile("save.txt");
string str = "";
getline(inputFile, str);
// now str contains the value of the whole line 


Basically, replace all of your current lines with getline().
getline(inputFile, wallet); // etc

-------------------------------------

Also, just a side note, your current method of loading data is effective for your small game as it exists currently, but when games get bigger you can't afford to write a whole line of code to load in every single value needed. It is much more effective to write a loop to read in all the values.

A loop like so would read the whole file:
1
2
3
4
5
6
7
8
9
// while not end of file
while (!inputFile.eof())
{
    string str = "";
    getline(inputFile, str);

    // then come up with a fancy way of storing
    // your data to make it efficient
}


We could get into data model stuff, but thats beyond the scope of your question. I don't want to get carried away. Haha. Let me know if you need anymore help.
Last edited on
ok, so getline worked for spliting the strings up. but when i load now the items that were getting split up are all in the wrong order, almost like the were loaded in the wrong sequence...
kind of hard to explain but it should look like

head [dirty bb cap]
torso [dirty tshirt]
legs [dity jeans]
hands [nothing]
feet [old sneakers]
holding [nothing][nothing]
gadget [nothing]

but instead ...
head [nothing]
torso [dirty bb cap]
legs [dirty tshirt]
hands [dirty jeans]
feet [nothing]
holding [old sneakers][nothing]
gadget []<<no string

i checked the save and load orders to make they were the same. (see initial post)

also, when trying to write into my two array's they come back completely empty.


any more ideas?

Last edited on
And that is the issue of mixing formatted and unformatted input: http://stackoverflow.com/a/21567292

TL;DR: std::getline(input >> std::ws, target);
Thank you, that took care of it!
Topic archived. No new replies allowed.