int n;
std::cin >> n;
std::string s = "";
std::getline(cin, s);
I noticed that if I use cin, my program would hang the next time I reach the line getline(cin, rangeInput).
Since getline() is using cin, is that why it is causing the program to hang if I have previously used cin? What should I do if I want to get a line after using cin?
You need to clear the input stream - try adding the following after your cin:
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
The accepted answer to this question gives a good explanation of why/when this is required.
std::cin leaves an extraneous \n in the input stream. When you use std::getline(), you are retrieving that \n.
Although #WilliamLannen's answer works if you really need std::cin, you are better off using this method:
int n;
std::string sn;
std::stringstream ssn;
std::getline(std::cin, sn);
ssn << sn;
ssn >> n;
References
http://www.daniweb.com/software-development/cpp/tutorials/71858
int n;
std::cin >> n;
std::cin.get() //<--- use cin.get() here ...
std::string s = "";
std::getline(cin, s);
Related
int n;
std::cin >> n;
std::string s = "";
std::getline(cin, s);
I noticed that if I use cin, my program would hang the next time I reach the line getline(cin, rangeInput).
Since getline() is using cin, is that why it is causing the program to hang if I have previously used cin? What should I do if I want to get a line after using cin?
You need to clear the input stream - try adding the following after your cin:
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
The accepted answer to this question gives a good explanation of why/when this is required.
std::cin leaves an extraneous \n in the input stream. When you use std::getline(), you are retrieving that \n.
Although #WilliamLannen's answer works if you really need std::cin, you are better off using this method:
int n;
std::string sn;
std::stringstream ssn;
std::getline(std::cin, sn);
ssn << sn;
ssn >> n;
References
http://www.daniweb.com/software-development/cpp/tutorials/71858
int n;
std::cin >> n;
std::cin.get() //<--- use cin.get() here ...
std::string s = "";
std::getline(cin, s);
In the following code, getline() skips reading the first line.
I noted that when commenting the "cin >> T" line, it works normally. But I can't figure out the reason.
I want to read an integer before reading lines! How to fix that?
#include <iostream>
using namespace std;
int main () {
int T, i = 1;
string line;
cin >> T;
while (i <= T) {
getline(cin, line);
cout << i << ": " << line << endl;
i++;
}
return 0;
}
cin >> T;
This consumes the integer you provide on stdin.
The first time you call:
getline(cin, line)
...you consume the newline after your integer.
You can get cin to ignore the newline by adding the following line after cin >> T;:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
(You'll need #include <limits> for std::numeric_limits)
Most likely there is a newline in your input file, and that is being processed immediately, as explained on this page:
http://augustcouncil.com/~tgibson/tutorial/iotips.html
You may want to call cin.ignore() to have it reject one character, but, you may want to read more of the tips, as there are suggestions about how to handle reading in numbers.
This line only reads a number:
cin >> T;
If you want to parse user input you need to take into account they keep hitting <enter> because the input is buffered. To get around this somtimes it is simpler to read interactive input using getline. Then parse the content of the line.
std::string userInput;
std::getline(std::cin, userInput);
std::stringstream(userInput) >> T;
Alright, this is for a project that's supposed to read in some code from a file with information on a student. However, it doesn't seem to be reading in anything from the file. I'm working in Visual Studio, and when I run it and pause at the end, I look at the vector I've created and it says there are no students in it. Student is a class I've created.
ifstream input;
string student_file;
cin >> student_file;
input.open(student_file);
double id_number = 0;
while (input >> id_number)
{
string name = "";
string address = "";
string phone_number = "";
cin.sync();
getline(input, name);
cin.sync();
getline(input, address);
cin.sync();
getline(input, phone_number);
Student * s = new Student(id_number, name, address, phone_number);
students.push_back(s);
}
The student class should be set up properly with a constructor and everything, so I'm assuming it's this code that's giving me the trouble. Even some direction on whether the problem is with the loop or my use of getlines would be helpful. Thanks!
This line:
while (input >> id_number)
extracts the integer from the input stream into id_number. When the extraction is finished, the newline character is still left in the stream. std::getline() is programmed to terminate extraction upon the discovery of the newline character (among other specifications).
To circumvent this situation, you need to discard the newline by using the std::ws manipulator. std::ws discards only leading whitespace from the stream. Newlines are considered whitespace. It is also advised that you check that your input succeeded by encasing the extraction in an if statement:
if (std::getline(input >> std::ws, name) &&
std::getline(input >> std::ws, address) &&
std::getline(input >> std::ws, phone_number))
Notice that I've also removed the std::cin.sync() between calls. Syncing the input buffer is not necessary in this context as stream insertion is not being performed, thus changes to the external sequence don't need to be regarded. Besides, the idea of syncing the input buffer of std::cin is non-nonsensical as std::cin is not affected whatsoever by the actions being taken on input.
And lastly, your vector that holds the student pointers should instead hold the actual objects themselves. This avoids the need for using dynamic memory allocation. The type of the vector should therefore be std::vector<Student>. And this is how you would construct the element in the vector:
students.emplace_back(id_number, name, address, phone_number);
Here is the full code:
#include <iostream>
#include <fstream>
#include <string>
int main()
{
std::ifstream input;
std::string student_file;
std::cin >> student_file;
input.open(student_file);
double id_number = 0;
std::vector<Student> students;
while (input >> id_number)
{
string name;
string address;
string phone_number;
if (std::getline(input >> std::ws, name) &&
std::getline(input >> std::ws, address) &&
std::getline(input >> std::ws, phone_number))
{
students.emplace_back(id_number, name, address, phone_number);
}
}
}
Basically I first takes an integer as input and then test case follows. My each test case is an string. I am suppose to print the string back if the starting patten of string matches "HI A" and it is case-insensitive. I wrote the code below to accomplish to this. My problem is that when I press enter after each input, getline takes newline character as new input. I have tried to tackle this by using extra getline after each input but the issue is still there. Program gets stuck in the loop even though I have put a break condition. What am I doing wrong?
#include <iostream>
#include <string>
using namespace std;
int main(){
int N;
cin >>N;
string nl;
getline(cin,nl);
for (int i=0;i<N;i++){
string s;
getline(cin,s);
//cout <<"string"<<s<<endl;
int flag=0;
if ((s.at(0)=='h'||s.at(0)=='H')&&(s.at(1)=='i'||s.at(1)=='I')&&(s.at(2)==' ')&&(s.at(3)=='a'||s.at(3)=='A')) flag=1;
if (flag==1) cout << s;
//cout << "not " <<s;
string ne;
cout << "i="<< i<<endl;
if (i==N-1) {break;}
getline(cin,ne);
}
}
Here is sample input:
5
Hi Alex how are you doing
hI dave how are you doing
Good by Alex
hidden agenda
Alex greeted Martha by saying Hi Martha
Output should be:
Hi Alex how are you doing
ignore() function does the trick. By default, it discards all the input suquences till new line character.
Other dilimiters and char limit can be specified as well.
http://www.cplusplus.com/reference/istream/istream/ignore/
In your case it goes like this.
cin >> N;
cin.ignore();
Your cin >>N stops at the first non-numeric character, which is the newline. This you have a getline to read past it, that's good.
Each additional getline after that reads the entire line, including the newline at the end. By putting in a second getline you're skipping half your input.
So, your real problem isn't that getline eats newlines, but that your second getline(cin, ne) is eating a line...
And that is because you mistakenly think that you need two getline operations to read one line - or something like that. Mixing "linebased" and "itembased" input does have confusing ways to deal with newlines, so you do need something to "skip" the newline left behind frin cin >> N;, but once you have got rid of that, you only need ONE getline to read up and including the newline at the end of a line.
I am writing this answer with the hopes that it may help someone else out there that wants a very simple solution to this problem.
In my case the problem was due to some files having different line endings such as '\r' vs. '\n'. Everything worked fine in windows but then it failed in Linux.
The answer was actually simple. I created a function removeNewLineChar after each line was read in. That way the char was removed. The removeNewLineChar takes in the line that was read in and copies it over character by character into a new string but it avoids copying either of the newline characters.
Here is an example:
string trim(string line)
{
string newString;
for (char ch : line)
{
if (ch == '\n' || ch == '\r')
continue;
newString += ch;
}
return newString;
}
//some function reading a file
while (getline(fin, line)) {
line = trim(line);
//... do something with the line
line = "";
}
you just need to accept the fact that getline will give you '\n' at the end. One solution is remove '\n' after getting it. Another solution is do not write the additional 'endl'. for example, for your problem, you can use this code
int N;
cin >> N;
string line;
getline(cin, line); // skip the first new line after N.
for (int i = 0; i < N; i++) {
string line;
getline(cin, line);
string first4 = line.substr(0, 4);
// convert to upper case.
std::transform(first4.begin(), first4.end(), first4.begin(), std::ptr_fun<int, int>(std::toupper)); // see http://en.cppreference.com/w/cpp/algorithm/transform
if (first4 == "HI A") {
cout << line; // do not include "<< endl"
}
}
cin.ignore() worked for me.
void House::provideRoomName()
{
int noOfRooms;
cout<<"Enter the number of Rooms::";
cin>>noOfRooms;
cout<<endl;
cout<<"Enter name of the Rooms::"<<endl;
cin.ignore();
for(int i=1; i<=noOfRooms; i++)
{
std::string l_roomName;
cout<<"Room"<<"["<<i<<"] Name::";
std::getline(std::cin, l_roomName);
}
}
std::string line;
std::cin>>std::ws; // discard new line not processed by cin
std::getline(std::cin,line);
From Notes section https://en.cppreference.com/w/cpp/string/basic_string/getline
When consuming whitespace-delimited input (e.g. int n; std::cin >> n;) any whitespace that follows, including a newline character, will be left on the input stream. Then when switching to line-oriented input, the first line retrieved with getline will be just that whitespace. In the likely case that this is unwanted behaviour, possible solutions include:
An explicit extraneous initial call to getline
Removing consecutive whitespace with std::cin >> std::ws
Ignoring all leftover characters on the line of input with cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
In the following code, getline() skips reading the first line.
I noted that when commenting the "cin >> T" line, it works normally. But I can't figure out the reason.
I want to read an integer before reading lines! How to fix that?
#include <iostream>
using namespace std;
int main () {
int T, i = 1;
string line;
cin >> T;
while (i <= T) {
getline(cin, line);
cout << i << ": " << line << endl;
i++;
}
return 0;
}
cin >> T;
This consumes the integer you provide on stdin.
The first time you call:
getline(cin, line)
...you consume the newline after your integer.
You can get cin to ignore the newline by adding the following line after cin >> T;:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
(You'll need #include <limits> for std::numeric_limits)
Most likely there is a newline in your input file, and that is being processed immediately, as explained on this page:
http://augustcouncil.com/~tgibson/tutorial/iotips.html
You may want to call cin.ignore() to have it reject one character, but, you may want to read more of the tips, as there are suggestions about how to handle reading in numbers.
This line only reads a number:
cin >> T;
If you want to parse user input you need to take into account they keep hitting <enter> because the input is buffered. To get around this somtimes it is simpler to read interactive input using getline. Then parse the content of the line.
std::string userInput;
std::getline(std::cin, userInput);
std::stringstream(userInput) >> T;