Creating a struct during while loop skips over input [duplicate] - c++

This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 1 year ago.
I'm trying to create a struct and collect its inputs from the user with a while loop, however on the second iteration it just seems to skip past the inputs.
#include <iostream>
#include <list>
struct Student {
std::string name;
std::string course;
float mark;
};
int main() {
std::list<Student> students;
while (students.size() < 2) {
Student student;
std::cout << "Student Name:" << std::endl;
std::getline (std::cin, student.name);
std::cout << "Course and Mark:" << std::endl;
std::cin >> student.course >> student.mark;
students.push_back(student);
}
for(auto const& student: students) {
std::cout << student.name << std::endl;
}
return 0;
}
The output looks like so:
Student Name:
Ari Stackoverflow
Course and Mark:
course543 56.2
Student Name: <---- skipped :(
Course and Mark:
Steve Jobs
As you can see, one the second iteration it skips over getting the name, not sure why.

The problem here is that when you press "Enter" after your second line of input, that newline is fed to std::getline(std::cin, student.name); on the next iteration. And so students[1].name would be an empty string.
To get around this, add std::cin.ignore() or std::cin.get() after reading your second line. This tells cin to ignore the newline.

Related

Getline command gets skipped when an integer cin statement is above [duplicate]

This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 2 years ago.
So I made this to try understanding classes and this error keeps coming up where in the command prompt tab, it doesn't ask the user to input the next required input when an integer is being asked. I added a comment in the code below for you to know where the error arises from.
#include <iostream>
using namespace std;
class Anime
{
public:
string Name;
int Year;
string Genre;
Anime(string aName, int aYear, string aGenre)
{
Name = aName;
Year = aYear;
Genre = aGenre;
}
};
int main()
{
string aniName;
int aniYear;
string aniGenre;
// This asks for the year
cout << "Anime Year: ";
cin >> aniYear;
// The "Anime Name" line runs but the input for aniName is not asked and skips to the next input
cout << "Anime Name: ";
getline(cin, aniName);
cout << "Anime Genre: ";
getline(cin, aniGenre);
Anime Anime1(aniName, aniYear, aniGenre);
cout << Anime1.Name << endl;
cout << Anime1.Year << endl;
cout << Anime1.Genre << endl;
}
When i make the integer the last input, it works perfectly, but at if I don't want it to be the last one. In that case, what do I do? Any answer is greatly appreciated.
Try to add #include <string>
And add below code upper the input code.
cin >> aniYear;
// The "Anime Name" line runs but the input for aniName is not asked and
skips to the next input
cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n');
cout << "Anime Name: ";
getline(cin, aniName);

C++ Why is my first data input with getline(cin, array[x]) is on the sameline and broken while my 2nd data input is fine? [duplicate]

This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 2 years ago.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int person;
cout << "How many person to data: ";
cin >> person;
int x = 0;
int i = 1;
string name[person];
string adress[person];
while(x < person){
cout << i << " person data" << endl;
cout << "Name: ";
getline(cin, name[x]);
cout << "Adress: ";
getline(cin, adress[x]);
cout << endl;
x++, i++;
}
for(x=0; x<person; x++){
cout << name[x] << setw(15) << adress[x] << endl;
}
}
This is my code to store a name and an adress into an array name[] and adress[]
And then i use for loop to print their name and adress
This is output image
Result
Why is my 1 person data broken?
The name and adress is on the same line while my 2nd person data is fine?
Its fine if i use cin >> but i use getline so i can a full name and an adress with the spaces
For starters variable length arrays
string name[person];
string adress[person];
is not a standard C++ feature. Instead use the standard container std::vector<std::string> like
#include <vector>
//...
std::vector<std::string> name( person );
std::vector<std::string> adress( person );
Or instead of two vectors you could declare a vector of objects of the type std::pair<std::string, std::string> like
#include <utility>
#include <vector>
//...
std::vector<std::pair<std::string, std::string>> persons( person );
In this case you should write in the loop like
//...
getline(cin, persons[x].first );
//...
getline(cin, persons[x].second);
After this input
cin >> person;
the input stream contains the new line character '\n' that corresponds to the pressed key Enter. You need to remove it before the while loop like
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
To do this you need to include the header <limits>.

How to terminate the '\n' for std::cin.get() [duplicate]

This question already has answers here:
std::cin input with spaces?
(8 answers)
Closed 5 years ago.
I would like to know how to get rid of the '\n' for when I execute cin.get(). For example:
#include <iostream>
int main() {
std::cout << "How many pieces of c: ";
struct c{
std::string name;
int val;
};
int amount;
std::cin >> amount;
c * c1 = new c[amount];
std::cin.get();
for(int i = 0; i < amount; i++){
std::cout << "C Number " << i + 1 << ":" << std::endl;
std::cout << "Please enter the name: ";
c1[i].name = std::cin.get();
std::cout << "Please enter the val: ";
std::cin >> c1[i].val;
std::cin.get();
}
return 0;
}
I've tried using cin.get() to eliminate the '\n' thats last read after my std::cin, but my program only takes in the first name and then executes the rest of the program without letting me continue to type the rest of the name and val values. In short, I want to be able to store the rest of my name and val values. Thanks!
c1[i].name = std::cin.get();
I'm not sure why you used get() instead of operator >>, like you did two lines later. get() reads a single character - meaning, only the first character you type in is saved as name. Everything else is read (most likely unsuccessfully) into val, and then new line character is, just like you intended, digested by the final get().
For reading int, try using getline and stringstream:
std::string input(5, '\0');
int number;
std::getline(std::cin, input);
std::stringstream sstrm(input);
sstrm >> number;
For a name: You can directly use getline
std::string name(30, '\0');
std::getline(std::cin, name);

when saving to file, words after white space are ignored [duplicate]

This question already has answers here:
How to read a complete line from the user using cin?
(4 answers)
Closed 6 years ago.
I've been working on saving to files and this was the result. The only problem is that anything after a space is ignored, (if you typed "john smith") it would print
("the last person to use this file was: john") I am using codeblocks with the GNU GCC compiler. Here is the code:
#include <iostream>
#include <cstdlib>
#include <fstream>
using namespace std;
int main()
{
string name;
ofstream saveData;
ifstream Data;
Data.open("Info.data", ios::binary);
Data >> name;
Data.close();
cout << "The last person to use the file was " << name << endl;
cout << "What is your name?" << endl;
cin >> name;
saveData.open("Info.data", ios::binary);
saveData << name;
cout << name << endl;
system("PAUSE");
saveData.close();
return 0;
}
thanks
For strings objects of ifstream (including cin) use input from beginning till the first space, and space is SPACE, TAB, and NELINE.
So, you should use getline instead cin >>
Try this:
Data.open("Info.data");
getline(Data, name);
Data.close();
and
cout << "What is your name?" << endl;
//cin >> name;
getline(cin, name);
UPDATE:
By the way, in your code
after
Data.open("Info.data", ios::binary);
you use
Data >> name;
So, stream opened in binary mode is read by >> - it is not so good.

Why won't getline function work multiple times in a for loop with an array of structures? [duplicate]

This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 7 years ago.
I have a little problem. I've created a program that asks user to enter part's name and part's price for four diffrent parts. Each name and price fills a structure, and I have an array of four structures. When i do a for loop to fill all the names and prices, my getline functon doesn't work properly, it simply just skipps the entering part after I enter the first part's name. Can you please tell me why?
Here's my code:
#include <iostream>
#include <string>
struct part {
std::string name;
double cost;
};
int main() {
const int size = 4;
part apart[size];
for (int i = 0; i < size; i++) {
std::cout << "Enter the name of part № " << i + 1 << ": ";
getline(std::cin,apart[i].name);
std::cout << "Enter the price of '" << apart[i].name << "': ";
std::cin >> apart[i].cost;
}
}
std::getline consumes the newline character \n, whereas std::cin will consume the number you enter and stop.
To illustrate why this is a problem, consider the following input for the first two 'parts':
item 1\n
53.25\n
item 2\n
64.23\n
First, you call std::getline, which consumes the text: item 1\n. Then you call std::cin >> ..., which recognises the 53.25, parses it, consumes it, and stops. You then have:
\n
item 2\n
64.23\n
You then call std::getline for a second time. All it sees is a \n, which is recognised as the end of a line. Therefore, it sees a blank string, stores nothing in your std::string, consumes the \n, and stops.
To solve this, you need to make sure the newline is consumed when you store the floating-point value using std::cin >>.
Try this:
#include <iostream>
#include <string>
// required for std::numeric_limits
#include <limits>
struct part {
std::string name;
double cost;
};
int main() {
const int size = 4;
part apart[size];
for (int i = 0; i < size; i++) {
std::cout << "Enter the name of part № " << i + 1 << ": ";
getline(std::cin,apart[i].name);
std::cout << "Enter the price of '" << apart[i].name << "': ";
std::cin >> apart[i].cost;
// flushes all newline characters
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}