c++ using pointers

Hi there

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.

Thank you
:)


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
// 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]

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
// 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.
Last edited on
Can you please edit your post and use the Code formatting tag to format your code.

What is the size of carts when calling loadCarts?
Last edited on
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.
How big us the array passed to 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?
Yes.
See kbw's question. How big is the array passed to loadCarts?

I'm guessing it is not big enough to store all the carts you are reading from the file.
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.
I take it that there's just room for one entry and you're treating it as an array of unspecified size.
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?
If you don't know beforehand how many entries you need to read, it'll be easier to use an std::vector.
Since I havent read about vectors yet I'll keep that aside for now while I do some studying on vectors. Thanks. :)

I am having another issue which I have posted above. Help with that will be much appreciated. Thanks again :)
Are you sure you're opening your files the correct way...

you have stuff like this...

ofstream dataFile(filename.c_str());

I think it's supposed to be something like this...

1
2
ofstream dataFile;
dataFile.open(filename.c_str(), ios::app );
Last edited on
No, std::ofstream dataFile(filename.c_str()); is fine; and I dare say, better..
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?
Topic archived. No new replies allowed.