Hello, OnlineGDB Q&A section lets you put your programming query to fellow community users. Asking a solution for whole assignment is strictly not allowed. You may ask for help where you are stuck. Try to add as much information as possible so that fellow users can know about your problem statement easily.

Getline problem

+1 vote
asked Jan 6 by leun (130 points)

I want to create a car program where the user will type in (in this case two) different cars. It will then be printed out accordingly. When I try to getline(car.brand) I get unintentded outputs in my terminal. However if I don't do getline to a string, it will work just fine. So the error lies in my getline. The only thing I can think of is a cin.ignore but even then, it isn't really needed according to my logic.

This is my desired output:

Enter cars:

Model: Volvo V70

Year: 2013

Milage: 100.1



Model: Chevrolet

Year: 2011

Milage: 2232.1

//Then here it will print out all the cars.

This is my output right now:

Enter cars:

Model: Volvo V70

Year: 2013

Milage: 100.1



Model: Year: 2013

Milage: 100.1

The brand Volvo V70 and the year 2013 and the price 122.1

The brand and the year 2013 and the price 100.1

Why is my Model and Year on my second loop cycle on the same row? Help is greatly appreciated.

Here is my code:

#include <iostream>

#include <iomanip>

#include <string>

#include <vector>



using namespace std;



struct Car_Type{

string model;

int year;

double milage;

};





void get (Car_Type & car)

{

cout << "Model: ";

getline(cin,car.model);

cout << "Year: ";

cin >> car.year;

cout << "Milage: ";

cin >> car.milage;

cout << endl;

}



void print_all (Car_Type const & car,

vector<Car_Type> const & cars)

{

for (Car_Type car : cars)

{

cout << "The brand " << car.model

<< " and the year " << car.year

<< " and the price " << car.milage << endl;

}

}



int main()

{

Car_Type car;

vector<Car_Type> cars;



cout << "Enter cars: " << endl;

for (int i {}; i < 2; ++i)

{



get(car);

cars.push_back(car);

}

print_all(car,cars);



return 0;


.I also tried doing cin.ignore() before my getline. It will let me input the car type but when I output the first cycle of the loop i will get the following results:

The brand olvo v70 and the year 2013 and the price 200.1

So it doesn't print out the first index of the string.

1 Answer

0 votes
answered Jan 9 by Peter Minarik (63,320 points)

I may be missing something here, but this is my understanding below.

You're mixing formatted (>>) and unformatted (getline()) input stream extraction functions. The formatted extraction ignores the newline, space, etc characters on the input stream, while the unformatted extraction does not.

So when you're done with your first car, you've finished your user input with a formatted extraction (cin >> car.milage;), which leaves the '\n' character on the cin.

You start your enquiries with a formatted input extraction (getline(cin, car.model);), which will read the leftover '\n' and be happy with it effectively setting your car model to an empty string.

To combat this, ideally, one would check before calling getline() if cin is empty then call ignore(). However, I didn't find something that quite does this, and calling every time will not achieve the desired behaviour. If you find such a check, please use that instead.

As a second-best scenario, I chose to remove anything left on the standard input after the last formatted extraction and now your code seems to work fine:

void get(Car_Type & car)
{
    cout << "Model: ";
    getline(cin, car.model);
    cout << "Year: ";
    cin >> car.year;
    cout << "Milage: ";
    cin >> car.milage;
    cout << endl;
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
Welcome to OnlineGDB Q&A, where you can ask questions related to programming and OnlineGDB IDE and and receive answers from other members of the community.
...