I have the following piece of code which is reading data from a text file. The problem is that when it reaches the (if (meal == "#") part it breaks and directs me to the source file of the meal class to the declaration of -
void Meal::setName(string name) {
this->name = name;
}
I am unable to figure out why it does this. It's a fairly extensive piece of code that I cant display all at once but if someone is willing to help me I'll show them the rest of the code too.
// load data from the named text file
// data format for a cart record is:
// owner
// location
// meal name
// meal cost
// meal rating
// ... (repeat meal name, cost, rating)
// #
//
// we are assuming that the file exists
// we assume that the records are correctly formated
int loadCarts(string filename,SnackCart carts[]) {
ifstream dataFile(filename.c_str());
int count = 0;
while(!dataFile.eof()) {
string owner;
getline(dataFile,owner);
if (owner == "") {
break; // stop read if reach end of file
} else {
carts[count].setOwner(owner);
string location;
getline(dataFile,location);
carts[count].setLocation(location);
carts[count].clearMeals();
bool moreMeals = true;
while (moreMeals) {
string meal;
getline(dataFile,meal);
if (meal == "#") {
moreMeals = false;
} else {
string numStr;
getline(dataFile,numStr);
float num = (float)atof(numStr.c_str());
string ratingStr;
getline(dataFile,ratingStr);
carts[count].addMeal(meal,num,ratingStr);
}
}
}
count++;
}
dataFile.close();
return count;
}
[code]
// save current collection of carts to the file
void saveCarts(string filename,SnackCart carts[],int count, int val) {
if (count == 0) {
cout << "Error: no carts to save yet" << endl;
return;
}
ofstream dataFile(filename.c_str(), ios::app);
for (int i = 0; i < count; ++i) {
dataFile << "Snackcart" << endl;
dataFile << carts[i].getOwner() << endl;
dataFile << carts[i].getLocation() << endl;
string *names = NULL;
names = new string[val];
int mealCount;
mealCount = carts[i].getMealNames(names);
for (int j = 0; j < mealCount; ++j) {
float cost = carts[i].getMealCost(names[j]);
string ratingStr = carts[i].getMealRatingForName(names[j]);
dataFile << names[j] << endl;
dataFile << cost << endl;
dataFile << ratingStr << endl;
}
dataFile << "#" << endl;
}
dataFile.close();
cout << "information saved" << endl;
}
/ add a new cart to the database
// assume that the meal names are unique
void addCart(SnackCart carts[], int& count, int &val) {
cout << "Enter number of snackcarts wanted: ";
int value_carts;
cin >> value_carts;
carts = new SnackCart[value_carts];
for (int x = 0; x < value_carts; ++x){
cout << "Enter Owner name: ";
string owner;
cin >> owner;
cout << "Enter cart location: ";
string location;
cin >> location;
cout << "Number of meal(s) for this cart: ";
cin >> val;
carts[count].setMealArray(val);
string meal;
float cost;
int mealCount = 0;
for (int i = 0; i <val; ++i){
cout << "Enter meal name:";
cin >> meal;
cout << "Enter cost for " << meal << ": ";
cin >> cost;
if (cost < 0) {
cout << "Error: invalid cost" << endl;
return;
}
carts[count].addMeal(meal, cost);
++mealCount;
}
if (mealCount == 0) {
cout << "Error: No meals entered, cart not added" << endl;
} else {
carts[count].setOwner(owner);
carts[count].setLocation(location);
++count;
}
}
}
the above two functions are for adding and saving carts. adding is working fine. but in the saving function it throws an exception when it encounters " dataFile << carts[i].getOwner() << endl; "
I have tried everything but i have no clue why it's doing this. the obejct carts has been declared as a pointer *carts and is of type SnackCart.
the number of carts is arbitrary in this case. it can be any number of carts. but for this case the text file has 3 carts. And the assumption in this case is that the first thing we are doing is calling loadCarts.
There's nothing obviously wrong with what you've posted. You could help yourself by stepping thru the code in a debugger or if your don't have one, inserting lines that print the state of variables as it runs.
im guessin something is wrong with the way the derived class (snackcart) is working with the base class. if i have a method (along with its definition) in the base class and the derived is publicly derived, the methods are avaiable as methods of the dervied class now as well. am i correct in saying that?
oh yeah i get what you mean now. the thing is that the carts object is dynamic. how would i set its size when the first call is loadCarts? assuming that the number of carts in the text file is unknown.
also while using the step into debugging method in visual studio 08, the line where the exception occurs is line 32 as seen above. the exception is a reading access violation.
but since its a dynamic array how would i set its size when reading from the file? the file can have one or ten entries. so how can i set its size in this case?
yes the second way is a shorter and more efficient method. either way both are correct. i was thinking that maybe overloading the stream operators should solve the problem. but the getOwner and getLocation methods only return the respectve values. So that is not the problem either. What else could be wrong with the code?