This question already has answers here:
Need help with getline() [duplicate]
(7 answers)
Closed 7 years ago.
I need to use getline to store whole line when user enters name and surname. When I run the program, it passes row of getline(cin,st[i].name); I mean the input function does not work, it skips next cin which is for "score".
struct Student {
string name;
int score;
char grade;
};
void main() {
int SIZE;
cout << " How many students are you going to add ? ";
cin >> SIZE;
Student* st = new Student[SIZE]; // user determines size of array.
int i;
for (i = 0; i < SIZE; i++)
{
if (st[i].name.empty()) // if array list of name is empty, take input.
{
cout << "name and surname : ";
//cin >> st[i].name;
getline(cin, st[i].name);
}
cout << "Score : ";
cin >> st[i].score; // take quiz score from user.
-- I did not put whole main function.
So when l run the program, back screen is shown
Is there any other way to get input for name ?
After cin >> SIZE;, the trailing newline is still kept in standard input.
You need cin.ignore() to skip the remaining newline character so the later getline() could get the value.
Related
I am trying to make a magic 8 ball that provides a random preset answer to any input except "bye". Each time the void function magic8ball() is called, it generates a random number from 0 - 19 and prints a corresponding response to the console.
int main()
{
string question;
cin >> question;
while (question != "bye") {
magic8ball();
cout << "~Ask another question.\n";
cin >> question;
}
return 0;
}
For some reason, if the input for question has more than one word / has whitespace between characters, the loop repeats for each word before asking for input again. I stuck a "cout << question << endl;" in there and it showed each word in the string (as well as a call of magic8ball and "ask another").
e.g
>hi frend
... Ask again later
hi
~Ask another question.
... Don't count on it
frend
~Ask another question.
How do I prevent the while loop from treating the string as a series of words? Why is cin not triggering along with magic8ball() and cout ?
std::cin stops reading when it sees whitespace. Space also counts as a whitespace.
If you want your string to have space, use std::getline()
int main()
{
string question;
std::getline(std::cin, question);
while (question != "bye") {
magic8ball();
cout << "~Ask another question.\n";
std::getline(std::cin, question);
}
return 0;
}
I am trying to create a program which obtains names and test scores and places them into separate vectors. I am using getline() so I can get both first and last names. However, whenever I use the below code every name after the first loses its first letter. So, if the input for names was John Smith, Jane Smith, Jacob Smith, etc. The program outputs John Smith, ane Smith, acob Smith,... I tried taking out the cin.ignore()'s but then the program runs through after the first entry. I also tried creating separate functions for obtaining the names and scores, but this did not work either. Any advice or help would be appreciated.
int main() {
string test_taker;
int num_of_students = 0;
cout << "How many students took the exam? ";
cin >> num_of_students;
int starting = 0;
vector <double> score_list_us(num_of_students);
vector <string> name_list_us(num_of_students);
vector<double> score_list_sorted(num_of_students);
vector<string> name_list_sorted(num_of_students);
for (int i =0; i < num_of_students; i++) {
cout << "Student #" << i + 1 << " Name: ";
cin.ignore();
getline(cin, name_list_us[i]);
cout << "Student #" << i + 1 << " Score: ";
cin >> score_list_us[i];
cin.ignore();
}...
Problem: Missing character
See that cin.ignore(); right in front of getline(cin, name_list_us[i]);? Guess what it does.
On the first pass through the loop that cin.ignore(); eats the newline left by cin >> num_of_students; Every other time through the loop there is no newline to be eaten, so it eats part of your data.
Solution
Always put ignore()s, if you can't avoid them entirely, AFTER the operation that left the garbage you want gone. If you put ignore() before another operation, sooner or later you're going to hit that operation without garbage in the stream. In this case you hit it sooner.
Next, you want to ignore() everything up to and including the newline. Anything the user typed in after the input we want is garbage and should be discarded. Otherwise ignore() takes out a space character or something equally useless and leaves the newline for getline to trip over. I'll leave it to an old friend to explain what you need to do.
Specifically, use
cin.ignore(numeric_limits<streamsize>::max(), '\n');
So
int main() {
string test_taker;
int num_of_students = 0;
cout << "How many students took the exam? ";
cin >> num_of_students;
// ignore after
cin.ignore(numeric_limits<streamsize>::max(), '\n');
int starting = 0;
vector <double> score_list_us(num_of_students);
vector <string> name_list_us(num_of_students);
vector<double> score_list_sorted(num_of_students);
vector<string> name_list_sorted(num_of_students);
for (int i =0; i < num_of_students; i++) {
cout << "Student #" << i + 1 << " Name: ";
// not before
getline(cin, name_list_us[i]);
cout << "Student #" << i + 1 << " Score: ";
cin >> score_list_us[i];
// because this guy eats the newlines
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Using getline() in C++
(7 answers)
Closed 4 years ago.
Can anyone explain why I am having trouble with the below C++ code?
#include <iostream>
using namespace std;
class stud
{
public:
string name,adrs;
long long unsigned int mob;
};
int main()
{
stud s[10];
unsigned int num;
cout << endl << "Enter the number of students(<10): ";
cin >> num;
cout << endl;
for(int i = 0; i < num; i++)
{
cout << endl << "Enter student " << i+1 << " name(put '.' at end and press enter): ";
getline(cin, s[i].name); // this line skips some data before even they are
//entered and there is no error while compiling
}
system("CLS");
for(int i = 0; i < num; i++)
{
cout << endl << " Student " << i+1 << " name is: ";
cout << s[i].name << endl;
}
return 0;
}
When I try to input a string value for an object in the array as above, using getline() without any delimiter (which uses a new line by default), I don't get correct output since some other data is automatically being skipped.
But, when I use getline() as follows instead of above, it works fine, but it needs a delimiter at the end:
getline(cin, s[i].name, '.');
Please help me find a solution. I think the Enter key is pressed several times at one key press, and that's why the getline() skips some data. I'm not sure about this, though.
before correcting you program one thing to know is that
Actually, a newline is always appended to your input when you select Enter or Return when submitting from a terminal.
cin>> doesn't remove new lines from the buffer when the user presses Enter.
This has little to do with the input you provided yourself but rather with the default behaviour std::getline() exhibits. When you provided your input for the name (std::cin >> num;), you not only submitted the following characters, but also an implicit newline was appended to the stream, getline() mistakes this for user input along with enter.
It is recommended to use cin.ignore() to get rid of those extra characters after using cin>>(whatever) if you are going to use getline(cin,any string) later.
Edit this part of your code:
stud s[10];
unsigned int num;
cout << endl << "Enter the number of students(<10): ";
cin >> num;
cout << endl;
cin.ignore();//just add this line in your program after getting num value through cin
//fflush(stdin);
//cin.sync();
//getchar();
for(int i = 0; i < num; i++)
{
cout<<endl<< "Enter student " << i+1 << " name(put '.' at end and press enter): ";
getline(cin,s[i].name);
}
system("CLS");
you can use and may be tempted to use fflush(stdin) also but it is not recommended as it has undefined behaviour, as
According to the standard, fflush can only be used with output buffers, and obviously stdin isn't one.
about cin.sync():
using “cin.sync()” after the “cin” statement discards all that is left in buffer. Though “cin.sync()” does not work in all implementations (According to C++11 and above standards).
you can also use getchar() to get the newline caused by Enter
This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 4 years ago.
Im using fgets(learner.name,21,stdin) to Input the name of the student but when i run the program ,it shows " Enter your name " and skips to "Enter your marks in 5 subjects. "
can someone explain me why this happening?Because it is same with cin.getline() function.
gets_s() function is not working compiler shows " 'gets_s' was not declared in this scope"
#include<iostream>
#include<stdio.h>
#include<cstdlib>
using namespace std;
struct Student
{
int rollno;
char name[21];
float marks[5];
char grade;
};
Student learner ;
int main()
{
cout<<"\n"<<"Enter Roll number: ";
cin>>learner.rollno;
cout<<"\n"<<"Enter your name: ";
fgets(learner.name,21,stdin);
cout<<"\n"<<"Enter your marks in 5 subjects: "<<"\n";
for(int i = 0;i <5;++i)
{
cout<<"\n"<<"Subject"<<i+1<<":";
cin>>learner.marks[i];
}
float avg ,total;
total = (learner.marks[0]+learner.marks[1]+learner.marks[2]+learner.marks[3]+learner.marks[4]);
avg = total/5;
if(avg<50)
learner.grade = 'D';
else if(avg<60)
learner.grade = 'C';
else if(avg<80)
learner.grade = 'B';
else
learner.grade = 'A';
cout<<"\n"<<"\n"<<"Student result: \n";
cout<<"Roll Number: "<<learner.rollno<<"\t";
cout<<"Name: ";
cout.write(learner.name,21);
cout<<"\n"<<"Total Marks: "<<total;
cout<<"\t"<<"Grade: "<<learner.grade<<endl;
system("pause");
return 0;
}
here is the output:
Enter Roll number: 22
Enter your name:
Enter your marks in 5 subjects:
Subject1:
The reason is that when you type roll no and press enter, cin only reads the number, not the newline (this is the default behaviour.). This newline remains in the input stream and when you execute fgets(), it takes in the newline character.
To change this you could use cin >> noskipws >> learner.rollno;
stdin buffer is not cleared after cin>>learner.rollno;, use getchar() to clear/flush the stdin buffer and then use cin.getline() as
cin.getline(learner.name,'\n');
This question already has answers here:
How to read n integers from standard input in C++?
(7 answers)
Closed 7 years ago.
So I want to split a string (entered to the console) into two integers.
The first integer will always be one digit at position 0 in the string. Then, there will be a space. Everything after that space will be the second digit.
Here is my code:
struct priority_element
{
int id;
int priority;
} priorityQueue[1000];
string input;
cin << input;
priority_element temp;
string priority = input.substr(0, 1);
string id = input.substr(1, input.size());
temp.priority = atoi(priority.c_str());
temp.id = atoi(id.c_str());
priorityQueue[0] = temp;
cout << priorityQueue[0].priority;
cout << priorityQueue[0].id;
I included the priority_element struct so you could see what it was.
I keep trying to enter a string, something like:
5 6
or
5 5000
I can print the priority (5), but printing the priority and id together like in my example code has the output of 50.
If I try to print the id alone then the output is empty.
Could anyone understand why this is happening?
Thanks!
std::cin will stop passing at spaces, so you should read the whole line to input by using
// cin >> input;
std::getline(cin, input);
As suggested by others, actually, this can be done simply by:
std::cin >> temp.priority >> temp.id;
The streams in C++ are made for just this type of thing.
(from iostream)
int x,y;
std::cin >> x;
std::cin >> y;
std::cout << x << y << std::endl;
string id = input.substr(1, input.size());
here you got a space not the second digit
English is not my first langage , hope you can understand