Creating files and opening previous files.

Need a little help here please.

This is what I need to do on this assignment:


Ask the user if this is a new or old (i.e. saved) pet.
If it is a new pet the constructor should work as before.
If it is an old pet the constructor should ask for the old pet's name. Then the constructor should open the file with that name and read in the pet's data.


I've been trying different things to get this to work, but I'm not having any such luck. Can anyone help me out with this? What am I doing wrong? What do you suggest? Any help would be greatly appreciated.

I'm a hands on learner, and learn by example, so I'm struggling with this class as my instructor does not do that very well.

Here is my code:

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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
#include<iostream>
#include<fstream>
#include<string>
using namespace std;

class pet{
private:
        int hunger;  // private data member
        int happy;   // private data member
        int health;
        int energy;
        string name; // private data member
public:
        pet(); // constructor
        void play();  // public member function
        void feed();  // public member function
        void vetvisit();
        void rest();
        void exercise();
        void print(); // public member function
        int check_health(); // public member function;

};


int main()
{
        pet pet1;
        int choice = 3;
        int health_check = 0;
        ofstream myfile;
        do{
                pet1.print();
                cout << "What would you like to do with your pet?\n";
                cout << " Play (1) \n Feed (2) \n Rest (3) \n Exercise (4) \n Vet Visit (5) \n Exit (0) \n";
                cin >> choice;
                switch(choice){
                case 1:
                        pet1.play();
                        break;
                case 2:
                        pet1.feed();
                        break;
                case 3:
                        pet1.rest();
                        break;
                case 4:
                        pet1.exercise();
                        break;
                case 5:
                        pet1.vetvisit();
                        break;
                }
                health_check = pet1.check_health();
        }while(choice != 0 && health_check != 1);
        myfile.close();
        return 0;
}

/* Constructor, creates a new pet with starting values. */
pet::pet(){


        int choice1 = 0;

        do{
        cout << "Is this a new pet? Yes (1) , No (2) " << endl;
        cin >> choice1;
        switch(choice1){

  case 1:
        hunger = 50;
        happy = 50;
        energy = 50;
        health = 50;
        cout << "Pet's name? (One word) ";
        cin >> name;
        ofstream myfile;
        myfile.open (name);
        cout << "Saving pet to a file."<< endl;
  case 2:
        cout << "What is your pets name?  ";
        cin >> name;
        ofstream myfile;
        myfile.open (name);
        }

} while (choice1 == 1 || 2);

}

/* Member function play(), allows playing with a pet. */
void pet::play(){
        int choice = 0;
        cout << "What should we play?\n";
        cout << " Fetch (1) \n Sit (2) \n Rollover (3) \n Shake (4) \n";
        cin >> choice;
        switch(choice){
        case(1):
                cout << " :-) \n";
                happy += 15;
                hunger -= 15;
                health += 10;
                energy -= 15;
                break;
        case(2):
                cout << " :-) \n";
                happy += 5;
                hunger -= 5;
                health += 2;
                energy -= 2;
                break;
        case(3):
                cout << " :-) \n";
                happy += 10;
                hunger -= 10;
                health += 5;
                energy -= 5;
                break;
        case(4):
                cout << " :-) \n";
                happy += 7;
                hunger -= 7;
                health += 3;
                energy -= 3;
                break;
        default:
                cout << "Not a valid choice." << endl;
        }
}
/* Member function feed(), allows the user to feed a pet. */
void pet::feed(){
        int choice = 0;
        cout << "What would you like to feed your pet?\n";
        cout << " Dry Food (1) \n Wet Food (2) \n Organic Food (3) \n";
        cin >> choice;
        switch(choice){

        case(1):
                cout << " :-) \n";
                happy += 15;
                hunger += 30;
                health += 10;
                energy -= 20;
                break;

        case(2):
                cout << " :-) \n";
                happy += 30;
                hunger += 30;
                health += 10;
                energy -= 20;
                break;
        case(3):
                cout << " :-) \n";
                happy -= 1;
                hunger += 30;
                health += 20;
                energy -= 20;
                break;
        }
}
void pet::rest(){
        int choice = 0;
        cout << "How long would you like to allow your pet to rest? \n";
        cout << " 1 hour (1) \n Half day (2) \n Overnight (3) \n";
        cin >> choice;

        switch(choice){
        case(1):
                cout << " :-) \n";
                happy += 10;
                hunger -= 10;
                health += 5;
                energy += 10;
                break;
        case(2):
                cout << " :-( \n";
                happy -= 15;
                hunger -= 15;
                health += 10;
                energy += 20;
                break;
        case(3):
                cout << " :-( \n";
                happy -= 30;
                hunger -=20;
                health += 5;
                energy += 40;
                break;
        }
}
void pet::exercise(){
        int choice = 0;
        cout << "What type of exercise? \n";
        cout << " Walk (1) \n Jog (2) \n Run (3) \n";
        cin >> choice;

        switch(choice){
        case(1):
                cout << " :-) \n";
                happy += 3;
                hunger -= 15;
                health += 5;
                energy -= 15;
                break;
        case(2):
                cout << " :-| \n";
                happy -= 5;
                hunger -= 25;
                health += 15;
                energy -= 20;
                break;
        case(3):
                cout << " :-( \n";
                happy -= 10;
                hunger -= 30;
                health += 35;
                energy -= 35;
                break;
        }
}

void pet::vetvisit(){
        cout << "Make sure you are watching your pet closely and doing whats best for your pet!\n";
        cout << " :,-( \n";
                happy -= 40;
                hunger -= 25;
                health += 50;
                energy -= 30;
}

/* Member function print(), prints information about a pet. */
void pet::print(){
        cout << "\nYour pet " << name << " is " << endl;
        cout << "Happy: " << happy << endl;
        cout << "Hungry: " << hunger << endl;
        cout << "Energy: " << energy << endl;
        cout << "Health: " << health << endl;
}

/* Member function check_health(), checks the health of a pet. */
int pet::check_health(){
        if(hunger <= 0){
                cout << "\nYour pet has starved.\n";
                return 1;
        }
        if(happy <= 0){
                cout << "\nYour pet has died of a broken heart.\n";
                return 1;
        }
        if(health <= 0){
                cout << "\nYour pet has become ill and died.\n";
                return 1;
        }
        if(energy <= 0){
                cout << "\nYour pet is too fatigued and died.\n";
                return 1;
        }
        if(hunger <= 20){
                health -= 15;
                happy -= 2;
                energy -= 2;
        }
        if(happy <= 20){
                health -= 15;
                energy -= 2;
                hunger -= 1;
        }
        if(energy <= 20){
                health -= 15;
                happy -= 2;
                hunger -= 1;
        }
        if(health <= 20){
                energy -= 2;
                happy -= 2;
                hunger -= 1;
        }
        if(health > 100){
                health -= 10;
        }
        if(happy > 100){
                happy -= 10;
        }
        return 0;
}
Where are you struggling? What is the exact problem that you are facing?
I'm having problems with writing a new file when a new pet is made, and recalling that file later if the user comes back later to play and wants to recall their pet.


This is not working, I know its wrong, I get errors telling me so... just not sure what to do anymore.

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
/* Constructor, creates a new pet with starting values. */
pet::pet(){


        int choice1 = 0;

        do{
        cout << "Is this a new pet? Yes (1) , No (2) " << endl;
        cin >> choice1;
        switch(choice1){

  case 1:
        hunger = 50;
        happy = 50;
        energy = 50;
        health = 50;
        cout << "Pet's name? (One word) ";
        cin >> name;
        ofstream myfile;
        myfile.open (name);
        cout << "Saving pet to a file."<< endl;
  case 2:
        cout << "What is your pets name?  ";
        cin >> name;
        ofstream myfile;
        myfile.open (name);
        }

} while (choice1 == 1 || 2);

}



Errors:
1
2
3
4
5
6
7
8
9
10
-bash-4.1$ g++ pet.cpp
pet.cpp: In constructor 'pet::pet()':
pet.cpp:85: error: no matching function for call to 'std::basic_ofstream<char, std::char_traits<char> >::open(std::string&)'
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/fstream:696: note: candidates are: void std::basic_ofstream<_CharT, _Traits>::open(const char*, std::ios_base::openmode) [with _CharT = char, _Traits = std::char_traits<char>]
pet.cpp:87: error: jump to case label
pet.cpp:84: error:   crosses initialization of 'std::ofstream myfile'
pet.cpp:90: error: redeclaration of 'std::ofstream myfile'
pet.cpp:84: error: 'std::ofstream myfile' previously declared here
pet.cpp:91: error: no matching function for call to 'std::basic_ofstream<char, std::char_traits<char> >::open(std::string&)'
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/fstream:696: note: candidates are: void std::basic_ofstream<_CharT, _Traits>::open(const char*, std::ios_base::openmode) [with _CharT = char, _Traits = std::char_traits<char>]

fstream::open() takes a c-string as parameter, not a std::string
myfile.open (name.c_str())

You forgot to put a break at the end of each case in the switch
Last edited on
Ok, I can't believe I missed the break.

Where would I place this?
myfile.open (name.c_str())
Are my previous placements wrong?
Do i need to place anything in the parentheses ?
Put that in place of your myfile.open(name)

The cross initialization error should be resolved by placing breaks
I put in the breaks and replaced myfile.open(name) with myfile.open (name.c_str())

I'm still getting errors though.

1
2
3
4
5
pet.cpp: In constructor 'pet::pet()':
pet.cpp:89: error: jump to case label
pet.cpp:84: error:   crosses initialization of 'std::ofstream myfile'
pet.cpp:92: error: redeclaration of 'std::ofstream myfile'
pet.cpp:84: error: 'std::ofstream myfile' previously declared here
Mmm ok, then you need to move the declaration of ofstream myfile outside of the do-while loop
Last edited on
ok, nevermind, I fixed that part. I moved ofstream myfile; to before the do statement, that worked. Problem I have now is once you either put in the pets name, or try to recall the old pet, it just asks you again if this is a new pet or an old pet, and it just does it over and over again instead of running the program...


Should I not use a switch to determine if it is a new pet or an old pet?
Last edited on
.. or you can create a new scope by putting the case code inside { }.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
switch(choice1) {
case 1: {
	hunger = 50;
	happy = 50;
	energy = 50;
	health = 50;
	cout << "Pet's name? (One word) ";
	cin >> name;
	ofstream myfile;
	myfile.open(name.c_str());
	cout << "Saving pet to a file."<< endl;
}
case 2: {
	cout << "What is your pets name?  ";
	cin >> name;
	ofstream myfile;
	myfile.open(name.c_str());
}
}


Note that a version of open and constructor taking std::string as argument was added for ifstream/ofstream in C++11. You compiler is too old to support this.
Last edited on
The condition for the loop is choice == 1 || 2
Given that if you enter either of them the condition is true and the loop is executed again, the correct syntax is

choice == 1 || choice == 2
The way you wrote it is interpreted as while(choice == 1 or true), because every value except 0 evaluates to true
Last edited on
this is what I get now.

1
2
3
4
5
6
7
-bash-4.1$ ./a.out
Is this a new pet? Yes (1) , No (2)
1
Is this a new pet? Yes (1) , No (2)
1
Is this a new pet? Yes (1) , No (2)


New code:

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
pet::pet(){


        int choice1 = 0;
        do{
        cout << "Is this a new pet? Yes (1) , No (2) " << endl;
        cin >> choice1;
        switch(choice1){

 case (1): {
        pet pet1;
        ofstream myfile;
        hunger = 50;
        happy = 50;
        energy = 50;
        health = 50;
        cout << "Pet's name? (One word) ";
        cin >> name;
        myfile.open (name.c_str());
        cout << "Saving pet to a file."<< endl;
        pet1.print();
        break;
}

  case (2):
        pet pet1;
        ofstream myfile;
        cout << "What is your pets name?  ";
        cin >> name;
        myfile.open (name.c_str());
        pet1.print();
        break;
        }

} while (choice1 == 1 || 2);
I fixed the choice, but it still just loops this section and won't move on to the rest of the program...

This is what I get after that:

1
2
3
4
5
6
7
8
9
10
-bash-4.1$ ./a.out
Is this a new pet? Yes (1) , No (2)
1
Pet's name? (One word) Dog
Saving pet to a file.
Is this a new pet? Yes (1) , No (2)
2
What is your pets name?  Dog
Is this a new pet? Yes (1) , No (2)
^C 
Last edited on
Post the code
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
pet::pet(){


        int choice1 = 0;
        do{
        cout << "Is this a new pet? Yes (1) , No (2) " << endl;
        cin >> choice1;
        switch(choice1){

  case (1): {
        ofstream myfile;
        hunger = 50;
        happy = 50;
        energy = 50;
        health = 50;
        cout << "Pet's name? (One word) ";
        cin >> name;
        myfile.open (name.c_str());
        cout << "Saving pet to a file."<< endl;
        break;
}

  case (2):
        ofstream myfile;
        cout << "What is your pets name?  ";
        cin >> name;
        myfile.open (name.c_str());
        break;
        }

} while (choice1 == 1 || choice1 == 2);


}
Ok, the syntax is correct, but like I said, if you enter 1 in choice the loop condition will be true and the loop will continue. You want the loop to continue only if the user enters an invalid choice, so it should be
while (choice1 != 1 || choice1 != 2)
There is no way choice1 != 1 || choice1 != 2 can be false. What you really want is
while (choice1 != 1 && choice1 != 2)
Ok, that didn't work either, I just removed the whole do process and it works.

My problem now is it is saving the numbers of each category all wrong...

-bash-4.1$ ./a.out
Is this a new pet? Yes (1) , No (2)
2
What is your pets name? Dog

Your pet Dog is
Happy: 63
Hungry: -1268712568
Energy: 0
Health: 4201184
What would you like to do with your pet?
Play (1)
Feed (2)
Rest (3)
Exercise (4)
Vet Visit (5)
Exit (0)
2
What would you like to feed your pet?
Dry Food (1)
Wet Food (2)
Organic Food (3)
2
:-)

Your pet has starved.
-bash-4.1$
Whoops that was embarrassing
Haha, its ok, you were helping, gave me new ideas to try. Thanks!

Now I just have to figure out whats up with the numbers...
Topic archived. No new replies allowed.