0

Need to do a project for school using arrays of class objects. We can't use vectors, so any answers suggesting them will not help. Ive been trying to create such and array, then put a name in each object. Ive tried running a for loop to do this, and it keeps skipping the first object in the array. Help?

#include <iostream>
#include <cstring>

using namespace std;

class Car
{
  private:
  char* driver;

  public:

  void setDriver(char* name)
  { 
     driver = name;
  }

  void getDriver()
  {
    cout<<driver;
  }

};

int main()
{

int numDrivers;
cout<<"How many drivers would you like?";
cin>>numDrivers;

Car* roster = new Car[numDrivers];

for(int i=0;i<numDrivers;i++)
{
  char* name;
  name = new char[20];
  cout<<"name:";
  cin.getline(name, 20);

  roster[i].setDriver(name);
}

for(int i=0;i<numDrivers;i++)
{
  roster[i].getDriver();
  cout<<".\n";
}
  return 0;
}

Ive toyed with the ranges of my for loops, it still always does the same thing when it hits the loop to set the names for the drivers. looks like this

How many drivers would you like?: 4
name:name: name1
name: name2
name: name3
.
name1.
name2.
name3.

any help is greatly appreciated.

TheTotalJim
  • 67
  • 2
  • 13
  • could you explain why you can't use vectors? Things like iostream and string library use lots of standard library functionality internally, so forbidding this seems totally arbitrary. – Marcus Müller Mar 28 '15 at 23:45
  • Tell your school it's 2015. Why not use the resources the compiler provides to avoid memory leaks and bugs? – Neil Kirk Mar 28 '15 at 23:49
  • As @user657267 said, it isn't your for loops it is that the `cin >> numDrivers` leaves the end of line in the input which is then read by your first `getLine` call. – The Dark Mar 28 '15 at 23:51
  • 2
    I hate comments like "use vectors, its 2015". There is a valid point in learning to use naked new/delete correctly, without practice, this is hard to learn. The fact that the code posted has many flaws is another matter... – jensa Mar 28 '15 at 23:56
  • @totaljim see the dupe, that's your problem, do not combine `cin` and `getline` without a `cin.ignore` in between. The `\n` read by `cin` remains in the buffer and is passed to `getline`. Quite a non-intuitive behaviour I'd say, but that's how `std::istream` works. – vsoftco Mar 28 '15 at 23:59
  • Can't use vectors because that was the assignment given, so I just want to finish it with what I was asked to use. @user657267 I think this may be the issue, i added cin.ignore(); in between the cout<<"name:"; and cin.getline(name, 20); and it stopped skipping my first entry, but then deletes the first letter when i print out the names looks like "name1 ame2 ame3" – TheTotalJim Mar 29 '15 at 00:02
  • @jensa, I agree you should learn old-style C-like programming also, but unfortunately most curricula teaches C++ like it's 1980, and introduces STL as an advanced subject. This is not the way to go, one should learn in parallel. STL is a great generic collection of algorithms and data structures one should definitely know about as soon as possible. It cannot hurt in any way. – vsoftco Mar 29 '15 at 00:03
  • also, thanks for the quick responses, ive been struggling with this all spring break. – TheTotalJim Mar 29 '15 at 00:04
  • @vsoftco I agree with that – jensa Mar 29 '15 at 00:05
  • _"We can't use vectors, so any answers suggesting them will not help"_ They'll help other people who are actually writing C++. This isn't your own personal helpdesk. – Lightness Races in Orbit Mar 29 '15 at 00:05
  • 2
    @vsoftco: There is no need to learn the STL in 2015. One should learn the C++ Standard Library that was introduced back in 1998 and has been updated several times since. – Lightness Races in Orbit Mar 29 '15 at 00:06
  • but in any case, the problem here is not `char*` vs `std::vector`, but the infamous `std::basic_istream`, which I still find a bit over-complicated. – vsoftco Mar 29 '15 at 00:07
  • @LightnessRacesinOrbit yes, true, but I was really talking about the STL component of the SL, namely the containers/iterators/algorithms (at least, that's how many people call this part of the Standard Library, although it is not a standard term). I think they are much more fundamental than e.g. type traits, at least for beginners. I agree one should eventually learn the Standard Library, but start at least with STL. I still have discussions about C qsort being faster than `std::sort`, because the former is written in C, so it must be faster, which is total non-sense. – vsoftco Mar 29 '15 at 00:08

2 Answers2

2

Per the comment, this same problem was answered in cin and getline skipping input

The exact way this affects your code is as follows. You execute these lines to read the number 4 (for example) from the input:

cout<<"How many drivers would you like?";
cin>>numDrivers;

The >> operator reads enough characters from cin to determine that there is a number 4 there (and that the number ends at 4). It does not read any farther, so anything else you might have typed on that line will still be there. If you hit the "return" key immediately after "4" then the only thing remaining on the line is the newline character that ends the line, but it's still there anyway.

The next interaction with the user is during the input loop when i is 0. This code executes:

  cout<<"name:";
  cin.getline(name, 20);

So the program prints "name" to the console and waits until there is some input terminated by a newline character. But there already is input like that waiting to be read (left over from cin>>numDrivers). So the program reads in the carriage return with nothing before it. It processes this as an empty string and goes on to the second iteration of the loop.

Community
  • 1
  • 1
David K
  • 3,147
  • 2
  • 13
  • 19
2

It seems the problems is that you have a 'dangling' \n newline character from the line

cin>>numDrivers;

The code above does not consume that new line character. so when the code gets to

cin.getline(name, 20);

It consumes the new line character as a line and moves one

The fix is to ignore all characters after your first call to cin as follows

void ignore_line ( std::istream& in )
{
    in.ignore ( std::numeric_limits<std::streamsize>::max(), '\n' );
}

int main()
{

    int numDrivers;
    cout<<"How many drivers would you like?";
    cin>>numDrivers;
    ignore_line(cin);  // Consume newline

    Car* roster = new Car[numDrivers];

    for(int i=0;i<numDrivers;i++)
    {
        char* name;
        name = new char[20];
        cout<<"name:";
        cin.getline(name, 20);

        roster[i].setDriver(name);
    }

    for(int i=0;i<numDrivers;i++)
    {
        roster[i].getDriver();
        cout<<".\n";
    }
    return 0;
}