doubt related to structure

Hi, I am a new c++ programmer. I just learned about structures and pointers, get() and getline(). I recently came across a problem in the book I am following, that I wasn't able to solve. Here goes:

The CandyBar structure contains three members. The first member holds the brand
name of a candy bar. The second member holds the weight (which may have a fractional part) of the candy bar, and the third member holds the number of calories (an integer value) in the candy bar.
Write a program that creates an array of three CandyBar structures (use new to allocate the array dynamically), initializes them to values of your choice, and then displays the contents of each structure.

Here's 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
// candybar3.cpp -- declaring an array of three candybar structures with new
#include <iostream>
#include <cstring>
using namespace std;
struct candybar
{
  char brand[20];
  double weight;
  int calories;
};
int main()
{
  using namespace std;
  int size;
  cout << "Enter the 3 as the size of the array: ";
  cin >> size;
  candybar *snack = new candybar[size];
 
  cout << "Enter the elements of the first array: ";
  cin.get(snack->brand, 20);
  cin.get();
  cin >> snack[0].weight;
  cin >> snack[0].calories;
  cout << endl;

  cout << "Enter the elements of the second array: ";
  cin.get(snack->brand, 20);
  cin >> snack[1].weight;
  cin >> snack[1].calories;
  cout << endl;

  cout << "Enter the elements of the third array: ";
  cin.get(snack->brand, 20);
  cin >> snack[2].weight;
  cin >> snack[2].calories;
  cout << endl;

  cout << "The elements of the first array are: ";
  cout << snack[0].brand;
  cout << snack[0].weight;
  cout << snack[0].calories;
  cout << endl;
  
  cout << "The elements of the second array are: ";
  cout << snack[1].brand;
  cout << snack[1].weight;
  cout << snack[1].calories;
  cout << endl;

  cout << "The elements of the third array are: ";	
  cout << snack[2].brand;
  cout << snack[2].weight;
  cout << snack[2].calories;
  cout << endl;

  return 0;
}


Although I am not getting any errors when I compile, I am not getting the right answer. I just learned about structures and pointers, and don't feel confident enough in this. So, I am not really sure what I am doing, but I tried. I need help solving this problem, and more importantly, I need help understanding structures - how and when to use them, how to display the contents of the structure etc.
Thanks in advance.
Last edited on
> I am not getting the right answer
maybe it would be a good idea to say what answer were you expecting and what did you get.
Yeah, sorry.. I was expecting to input values for each array, and get the output like this:
Name
Weight
Calories
Instead, when I run the program it goes like this:
Enter the 3 as the size of the array: 3 //(the question wants an array of 3 candybar structures)
Enter the elements of the first array:
Enter the elements of the second array:
Enter the elements of the third array:
The elements of the first array are: 00
The elements of the second array are: 00
The elements of the third array are: 00
1. You don't need to request the size. Just assign size the value 3.

2. After you are done with the array, free the memory by adding delete[] snack;

3. snack->brand is equivalent to (*snake).brand. Since *snake returns the first element pointed by snake, you are always assigning/re-assigning the brand name of the first element. Use snack[0].brand, snack[1].brand and snack[2].brand instead, as in your output statement.

4. You should not write the same code twice. Try using a for loop.

5. Use std::string brand; and read them by std::getline(std::cin, snack[offset].brand); You do not need to discard the newline char left. getline will do it for you.
Your cin statements for brand are faulty.
They should be:
1
2
3
4
5
6
7
8
9
10
cin >> snack[0].brand;
...
cin >> snack[1].brand;
...
cin >> snack[2].brand;
Enter the 3 as the size of the array: 3
Enter the elements of the first array: Mars 5 240

Enter the elements of the second array: M&M 10 500

Enter the elements of the third array: Snickers 10 1000

The elements of the first array are: Mars 5 240
The elements of the second array are: M&M 10 500
The elements of the third array are: Snickers 10 1000

@ Nikko YL :
3. Since *snake returns the first element pointed by snake, you are always assigning/re-assigning the brand name of the first element.
=> Does this mean that I was taking in some value (say Snickers) for the first array, and replacing it with another value (say Mars) for the second array. I didn't quite understand.
But both your and AbrstractionAnon's point using snack[0].brand was right. Thanks for that!

4. I haven't learned about loops yet, it's the next chapter. I am learning using c++ primer plus.

5. I tried using string brand and getline, but I am getting a problem:
You see, the book gives a sample input like so:
"Mocha Munch", 2.3, and 350. But, when i enter the input like this: Mocha Munch 2.3 350, it just stalls.
Here's what my code looks like now:

// candybar3.cpp -- declaring an array of three candybar structures with new
#include <iostream>
#include <cstring>
using namespace std;
struct candybar
{
string brand;
double weight;
int calories;
};
int main()
{
using namespace std;

candybar *snack = new candybar[3];

cout << "Enter the elements of the first array: ";
getline(cin, snack[0].brand);
cin >> snack[0].weight;
cin >> snack[0].calories;
cout << endl;

cout << "Enter the elements of the second array: ";
getline(cin, snack[1].brand);
cin >> snack[1].weight;
cin >> snack[1].calories;
cout << endl;

cout << "Enter the elements of the third array: ";
getline(cin, snack[2].brand);
cin >> snack[2].weight;
cin >> snack[2].calories;
cout << endl;

delete[] snack;

cout << "The elements of the first array are: ";
cout << snack[0].brand << endl;
cout << snack[0].weight << endl;
cout << snack[0].calories << endl;
cout << endl;

cout << "The elements of the second array are: ";
cout << snack[1].brand << endl;
cout << snack[1].weight << endl;
cout << snack[1].calories << endl;
cout << endl;

cout << "The elements of the third array are: ";
cout << snack[2].brand << endl;
cout << snack[2].weight << endl;
cout << snack[2].calories << endl;
cout << endl;

return 0;
}

This is what the output looks like:
Enter the elements of the first array: Mocha Munch 2.3 350

Then it stalls.
I'd move the delete [] to after the cout statements, since you still need to access the dynamically allocated memory for the output.
Line 2: Header should be <string>, not <cstring>

How are you entering the input? Because you changed brand to use getline, the runtime is expecting the enter key after brand, then two numbers on the same line:
1
2
Snickers <enter>
5 250 <enter>

@AbstractionAnon : I changed the header to <string>
I am entering each input separately (pressing enter after each input). I also tried, entering input your way.
The program accepts only the first input, then does not take any further values. Here's the output:

Enter the elements of the first array: Mocha Munch
2.3 350

Enter the elements of the second array: Chocolate Cake

Enter the elements of the third array:
The elements of the first array are: Mocha Munch
2.3
350

The elements of the second array are:
0
0

The elements of the third array are:
0
0


The only changes I made to the program are:
I changed the header from <cstring> to <string> and I placed delete[] snack after the cout statements.
Everything else remains the same.
Because there is a newline char left after the input for snack[0].calories.
After each cin >> calories, add a cin.get();.
You can think of snack->brand as snack[0].brand, given that snack is an array.
If all input succeeds, snack[0].brand would be the last input while snack[1].brand and snack[2].brand would be empty strings.

Btw, an array stores elements.
snack is the array.
snack[0], snack[1] and snack[2] are elements.
I'd use a loop instead of retyping the same code over and over again.

1
2
3
4
5
6
7
8
9
10
11
12
13
    int size = 3;
    
    candybar *snack = new candybar[size];

    for (int i=0; i<size; i++)
    {
        cout << "Enter the elements of the snack " << i+1 << " :\n";
        getline(cin, snack[i].brand);
        cin >> snack[i].weight;
        cin >> snack[i].calories;
        cin.ignore(100, '\n');    // discard newline
        cout << endl;
    }
@Nikko YL:
I used cin.get() after each cin >> calories;
The program is still not accepting values and is stalling.


I finally got it. I used cin.get(); after every snack[].weight and snack[]calories.

Thanks for all the help, I appreciate it.
@Chervil:

I understand that loops would make it easier, but I haven't learned about it yet! ( I mentioned it earlier in this post). But, thanks for the advice.
How come you have learnt dynamic memory allocation using new but not loop.
The book I follow: C++ Primer Plus has the chapter on structures and pointers preceding the chapter on loops. I guess I'll learn that in the next chapter.
Topic archived. No new replies allowed.