Hey there! I'm new to c++ and programming in general and have a quick question to why the program below works. I had most of it completed but for hours i couldn't figure out why every time i tried to enter input for the "make" member of my dynamic structure array it would just skip over it in the program. I added the cin.get(); right before the getline(cin, carArray[i].make); and all of a sudden it worked. I guess I wanna know why the getline() was dependent on the cin.get() being present.
Any help would be greatly appreciates cause that was frustrating as hell!

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
using namespace std;

struct car {
    string make;
    int yearBuilt;
};



int main()
{
    cout << "How many cars would you like to catalog?" << " ";
    int numCars;
    cin >> numCars;


    car * carArray = new car[numCars];

    for (int i = 0; i < numCars; i++)
    {
        cout << "Car " << ++i << " : ";
        --i;
        cout << "\nPlease enter the make: ";
        cin.get();
        getline(cin, carArray[i].make);
        cout << "Please enter year built: ";
        cin >> carArray[i].yearBuilt;
    }

    cout << "\n\nHere is your Collection:  \n\n";

    for (int j = 0; j < numCars; j++)
    {
        cout << carArray[j].yearBuilt << " " << carArray[j].make << "\n";
    }


}

Dani AI

Generated

Nice find, — the program behaved exactly as you described because a formatted extraction left a leftover character in the input stream and std::getline then saw that leftover immediately. and correctly pointed to that symptom; the next step is picking a robust fix and understanding the tradeoffs.

Formatted extraction (the >> operator) skips leading whitespace, reads characters that match the target type, then stops at the first non-matching character without removing it. std::getline reads until the next newline. If the newline (or other leftover) is already in the stream, getline returns an empty string. Consuming exactly one character with cin.get() fixes the specific case, but it is a brittle shortcut when there might be more left in the buffer.

Practical, safer options:

#include <limits>

// discard everything up to and including the next newline
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
#include <iostream>
#include <string>

// discard leading whitespace (including a leftover newline) right before getline
std::string make;
std::getline(std::cin >> std::ws, make);
#include <string>

// read a whole line and parse the number to avoid mixing extraction styles
std::string line;
std::getline(std::cin, line);
int numCars = std::stoi(line); // handle exceptions or validate

See std::istream::ignore, std::getline, and std::ws for details. Also validate inputs and handle std::cin.fail() (clear + ignore) when parsing user data. For robust user-facing code, prefer reading full lines and parsing them, or consistently use one input style rather than mixing >> and getline.

Recommended Answers

All 3 Replies

you need cin.get or cin.ignore before getline, because if there are any characters in the stream when getline is called, getline will just grab those characters instead of what you intend it to receive. If you have not entered any characters before hand into the cin stream, you wouldn't need to call cin.get or cin.ignore, but when you entered how many cars you wanted to catalog, it threw those characters into the stream.

Simpler version of your problem:

#include <iostream>
int main(){
 using namespace std;
 int a = 0;
 string str;
 cin >> a;
 getline(cin,str); //skipped??
}

the problem is when you use cin to read in a number, there is a newline that gets
stuck in the buffer, because cin disregards whitespaces and newlines. Thus that
newline is read into the string, and does not read in the user input. So to solve
this problem, you need to read the buffer to discard the newline. There are many
solutions to this. One ways is the way you found it, using cin.get. Others uses
cin.ignore and such.

Ok that makes sense. Thanks guys, now I can sleep tonight!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.