problem in output

Hi, I am new to c++ and programming. I was solving the following question:
Design a structure called car that holds the following information about an automobile: its make, as a string in a character array or in a string object, and the year it was built, as an integer. Write a program that asks the user how many cars to catalog. The program should then use new to create a dynamic array of that many car structures. Next, it should prompt the user to input the make (which might consist of more than one word) and year information for each structure. Finally, it should display the contents of each structure. A sample run should look something like the following
How many cars do you wish to catalog? 2
Car #1:
Please enter the make: Hudson Hornet
Please enter the year made: 1952
Car #2:
Please enter the make: Kaiser
Please enter the year made: 1951
Here is your collection:
1952 Hudson Hornet
1951 Kaiser

Here's my code for the problem:

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
// car.cpp -- creating a car structure to hold info about automobile
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
struct car
{
  string make;
  int year;
};
int main()
{
  int num;
  cout << "How many cars do you wish to catalog? ";
    cin >> num;
  
  car *catalog = new car[num];

  for (int i = 0; i < num; ++i) {
    cout << "Please enter the make: " << endl;
    getline(cin, catalog[i].make);
    cout << "Please enter the year made: " << endl;
    (cin >> catalog[i].year).get();
  }

  for (int i = 0; i < num; ++i) {
    cout << catalog[i].year << " " << catalog[i].make << endl;
  }

  delete [] catalog;

  return 0;

}
 


Here's the output:
How many cars do you wish to catalog? 2
Please enter the make:
Please enter the year made:
Hudson Hornet
Please enter the make:
Please enter the year made:
0
0


I think there's something wrong with the input statements. I don't know what exactly.
Sorry for the long post. Thanks in advance for the help.
Please explain line 23.
It's taking the year input for the new car structure
It does more than that; it calls cin.get() too. Why?

Is it because you want to get rid of a newline that (presumably) follows the number so that the next call to getline does not take that (empty) tail rather than the following line that has a name?

If yes, then should line 15 read (cin >> num).get()
or perhaps (cin >> num).ignore(256, '\n')
@keskiverto:

I'm sorry, I didn't understand this part:

If yes, then should line 15 read (cin >> num).get()
or perhaps (cin >> num).ignore(256, '\n')
You read a number with >>. The user probably finishes the number with Enter, i.e. a newline. The newline remains in the stream.

The next thing you do is to read a line with getline. That is an empty string, because the first character in stream is that newline.

We proceed to read the year. The user gives us "H...". Reading year fails and stream is now in state "fail". All further input fails automatically.

Therefore, replace line 15 with:
1
2
cin >> num;
cin..ignore(256, '\n');

Now you can paste some trailing junk with the number and the ignore will get rid of it.
I'm sorry but, it still doesn't fix it.

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
// car.cpp -- creating a car structure to hold info about automobile
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
struct car
{
  string make;
  int year;
};
int main()
{
  int num;
  cout << "How many cars do you wish to catalog? ";
    cin >> num;
  
  car *catalog = new car[num];

  for (int i = 0; i < num; ++i) {
    cout << "Please enter the make: " << endl;
    getline(cin, catalog[i].make);
    cin.get();
    cout << "Please enter the year made: " << endl;
    (cin >> catalog[i].year).get();
    cin.get();
  }

  for (int i = 0; i < num; ++i) {
    cout << catalog[i].year << " " << catalog[i].make << endl;
  }

  delete [] catalog;

  return 0;

}


Here's the output I am getting:

How many cars do you wish to catalog? 2
Please enter the make:
Kaiser 1942
Please enter the year made:
Please enter the make:
Please enter the year made:
0
0
Adding stuff into the loop was not even discussed. Note:
1
2
3
4
5
6
7
(cin >> catalog[i].year).get();
cin.get();

// means exactly the same as
cin >> catalog[i].year;
cin.get();
cin.get();


Lets do something else for a while:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
size_t num {0};
cin >> num;
cin.ignore(256, '\n'); // Discard the rest of line after the num

if ( 0 < num ) {
  std::vector<car> catalog( num );
  car value;
  size_t count {0};
  while ( count < num &&
          getline(cin, value.make) &&
          cin >> value.year )
  {
    catalog[count] = value;
    ++count;
    cin.ignore(256, '\n'); // Discard the rest of line after the year
  }

  for ( const auto & v : catalog ) {
    cout << v.year << " " << v.make << '\n';
  }
}

Once before loop, once within the loop.
Last edited on
@keskiverto:

Will this fix it:
If I use

1
2
3
cin.getline(catalog->make,20);     // line 21

cin >> (*catalog).year;           // line 24 
1. Please note that
1
2
3
4
5
catalog->make
// is same as
(*catalog).make
// is same as
catalog[0].make

(Same with the 'year')

Your proposed change modifies the first element of the array on every iteration and never updates the other elements.


You could take my code and revert the catalog back to your dynamic array. That requires changes only on lines 6, 18, 19, and 21.
Thanks for the reply.

Here's my final 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
// car.cpp -- creating a car structure to hold info about automobile
#include <iostream>
#include <string>
#include <cstring>
#include <cstdio>
using namespace std;
struct car
{
  string make;
  int year;
};
int main()
{
  int num;
  cout << "How many cars do you wish to catalog? ";
  cin >> num;
  
  car *catalog = new car[num];

  for (int i = 0; i < num; ++i) {
    cout << "Please enter the make: " << endl;

    cin >> catalog[i].make;
    cin.ignore(1, '\n');

    cout << "Please enter the year made: " << endl;
    cin >>  catalog[i].year;
    cin.ignore(1, '\n');

  }

  for (int i = 0; i < num; ++i) {
    cout << catalog[i].year << " " << catalog[i].make << endl;
  }

  delete [] catalog;

  return 0;

}


For the 'make' it unfortunately accepts only a single word (e.g. Hudson instead of Hudson Hornet).
I tried using getline, but then it causes a fatal error. Is there any way I can fix this.
@keskiverto:
I could use your code, but I feel I understand my way better (only if I could fix it!).
Thanks for all the help!
You have these lines:
1
2
3
4
5
6
7
8
  for (int i = 0; i < num; ++i)
  {
    cin >> catalog[i].make;
    cin.ignore(1, '\n');

    cin >>  catalog[i].year;
    cin.ignore(1, '\n');
  }

Try these instead:
1
2
3
4
5
6
7
  for (int i = 0; i < num; ++i)
  {
    cin.ignore(1, '\n');
    getline( cin, catalog[i].make );

    cin >>  catalog[i].year;
  }
Thanks a ton!! It works!

I see that it was mostly reordering, right? How did it make such a difference?
Is cin.ignore(1, '\n') the same as using cin.get() ??
Topic archived. No new replies allowed.