How to Differentiate Number 10 from '\n' in a Loop-Continuation Condition? - c++

I have the following portion of code:
cout << "Enter a series of integers: ";
cin >> integer;
while (integer != '\n')
{
cout << ...
cin >> integer;
} // end while
If the user enters 10, my loop is breaking because number 10 = '\n' value in decimal.
How can I get around this issue?
Thanks,

Your attempted code does not work because the operation cin >> integer extracts digits and converts them to an int. It cannot distinguish where the end of the line was.
Instead you should read a complete line, and then extract integers out of that line, e.g.:
std::string s;
std::getline(std::cin, s);
std::istringstream iss(s);
int integer;
while ( iss >> integer )
{
// do something with integer
}

Consider reading the user's input into a std::string first.
If it's not the newline, convert to an int and do your work.
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
int main(){
std::string integer;
cout << "Enter a series of integers: ";
cin >> integer;
while (integer != "x") //<- can't be whitespace
{
cout << atoi(integer.c_str()) << std::endl;
cin >> integer;
}
}

By default, input streams will skip any whitespace, including newlines. In other words, you will never have a ten in the input value unless someone entered "10". The general way to handle input is to read until reading fails (e.g. due to EOF):
while(cin >> value)
{
// use value here
}
// failure, EOF or garbage on input
Note that you will have to cin.clear() the stream before reading anything else afterwards, and that you still have the garbage in there that you have to cin.ignore(..). Maybe you want to use line-based input using getline() instead, and then simply check if the resulting string is empty or (try to) parse it as an integer otherwise.

#include <iostream>
int main(void)
{
int integer = 0;
std::cout << "Enter a series of integers: ";
std::cin >> integer;
while (integer != '\n' || integer == 10) {// **this will not work, it's wrong!**
std::cout << integer << std::endl;
std::cin >> integer;
}//end while
return 0;
}

Related

Can someone rectify the code and explain why gets() is not reading the value properly? [duplicate]

This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 2 years ago.
I need the following program to take the entire line of user input and put it into string names:
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
getline(cin, names);
With the cin >> number command before the getline() command however (which I'm guessing is the issue), it won't allow me to input names. Why?
I heard something about a cin.clear() command, but I have no idea how this works or why this is even necessary.
cout << "Enter the number: ";
int number;
cin >> number;
cin.ignore(256, '\n'); // remaining input characters up to the next newline character
// are ignored
cout << "Enter names: ";
string names;
getline(cin, names);
Another way of doing it is to put a
cin.ignore ( std::numeric_limits<std::streamsize>::max(), '\n' );
after your cin>>number; to flush the input buffer completely (rejecting all of the extra characters until a newline is found). You need to #include <limits> to get the max() method.
cout << "Enter the number: ";
int number;
if (cin >> number)
{
// throw away the rest of the line
char c;
while (cin.get(c) && c != '\n')
if (!std::isspace(c))
{
std::cerr << "ERROR unexpected character '" << c << "' found\n";
exit(EXIT_FAILURE);
}
cout << "Enter names: ";
string name;
// keep getting lines until EOF (or "bad" e.g. error reading redirected file)...
while (getline(cin, name))
...use name...
}
else
{
std::cerr << "ERROR reading number\n";
exit(EXIT_FAILURE);
}
In the code above, this bit...
char c;
while (cin.get(c) && c != '\n')
if (!std::isspace(c))
{
std::cerr << "ERROR unexpected character '" << c << "' found\n";
exit(EXIT_FAILURE);
}
...checks the rest of the input line after the number contains only whitespace.
Why not just use ignore?
That's pretty verbose, so using ignore on the stream after >> x is an oft-recommended alternative way to discard content through to the next newline, but it risks throwing away non-whitespace content and in doing so, overlooking corrupt data in the file. You may or may not care, depending on whether the file's content's trusted, how important it is to avoid processing corrupt data etc..
So when would you use clear and ignore?
So, std::cin.clear() (and std::cin.ignore()) isn't necessary for this, but is useful for removing error state. For example, if you want to give the user many chances to enter a valid number.
int x;
while (std::cout << "Enter a number: " &&
!(std::cin >> x))
{
if (std::cin.eof())
{
std::cerr << "ERROR unexpected EOF\n";
exit(EXIT_FAILURE);
}
std::cin.clear(); // clear bad/fail/eof flags
// have to ignore non-numeric character that caused cin >> x to
// fail or there's no chance of it working next time; for "cin" it's
// common to remove the entire suspect line and re-prompt the user for
// input.
std::cin.ignore(std::numeric_limits<std::streamsize>::max());
}
Can't it be simpler with skipws or similar?
Another simple but half-baked alternative to ignore for your original requirement is using std::skipws to skip any amount of whitespace before reading lines...
if (std::cin >> number >> std::skipws)
{
while (getline(std::cin, name))
...
...but if it gets input like "1E6" (e.g. some scientist trying to input 1,000,000 but C++ only supports that notation for floating point numbers) won't accept that, you'd end up with number set to 1, and E6 read as the first value of name. Separately, if you had a valid number followed by one or more blank lines, those lines would be silently ignored.
Try:
int number;
cin >> number;
char firstCharacterOfNames;
cin >> firstCharacterOfNames; // This will discard all leading white space.
// including new-line if there happen to be any.
cin.unget(); // Put back the first character of the name.
std::string names;
std::getline(cin, names); // Read the names;
Alternatively. If you know that number and names will always be on different lines.
cin >> number;
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::getline(cin, names);
You can use std::ws to extract any whitespace characters in the input buffer before using getline. Header for std::ws is sstream.
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
cin>>ws;
getline(cin, names);
Try cin.ignore() when you use cin before getline() function
void inputstu(){
cout << "Enter roll Number:";
cin >> roll_no;
cin.ignore(); //ignore the withspace and enter key
cout << "Enter name:";
getline(cin, stu_name);
}
Or you can flush the input buffer to read the string
fflush(stdin)
it is defined in header stdio.h.
This code works..
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
fflush(stdin); //FLUSHING STDIN
getline(cin, names);
i just used
getline(cin >> ws,lard.i_npute);
with the standard
#include <iostream>
header in the instances where I was having problems with carriage returns and the ws manipulator worked. I will probably start embedding looping functions as classes and using constructor and destructor calls atleast.
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
getline(cin, names);//works on the \n left behind
getline(cin, names);//continues and rewrites names
its pretty self explainatory, there is a \n left behind in the stream that cin >> number uses, which gets assigned to names the first time its used. Reusing the getline writes the correct value now.
You can find the answer you want in cppreference.
When used immediately after whitespace-delimited input, e.g. after int n; std::cin >> n;, getline consumes the endline character left on the input stream by operator>>, and returns immediately. A common solution is to ignore all leftover characters on the line of input with cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); before switching to line-oriented input.
you want to use cin.ignore() after your cin statements because you want to ignore the "\n" left in the buffer after taking your int variable with cin.
i have a similar program i used with a similar problem:
#include <iostream>
#include <iomanip>
#include <limits>
using namespace std;
int main() {
int i = 4;
double d = 4.0;
string s = "HackerRank ";
// Declare second integer, double, and String variables.
int n;
double d2;
string str;
// Read and save an integer, double, and String to your variables.
cin >> n;
cin >> d2;
cin.ignore();
getline(cin, str);
// Print the sum of both integer variables on a new line.
cout << i + n << endl;
// Print the sum of the double variables on a new line.
cout << d + d2 << endl;
// Concatenate and print the String variables on a new line
cout << s << str << endl;
// The 's' variable above should be printed first.
return 0;
}
Conceptually, I think you want each answer to be neatly one line. So why don't you try this?
cout << "Enter the number: ";
string line;
getline(cin, line);
int number = std::stoi(line);
cout << "Enter names: ";
string names;
getline(cin, names);
The code consumes the first newline character correctly, gives you the number if the line is correct or throws an exception if it is not. All for free!
#include <iostream>
#include <string>
using namespace std;
int main()
{
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
// USE peek() TO SOLVE IT! ;)
if (cin.peek() == '\n') {
cin.ignore(1 /*numeric_limits<streamsize>::max()*/, '\n');
}
getline(cin, names);
return 0;
}
Just peek ahead using cin.peek() and see if a '\n' is still left in cin's internal buffer. If so: ignore it (basically skip over it)

When I repeat the program it skips array entry [duplicate]

This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 2 years ago.
I need the following program to take the entire line of user input and put it into string names:
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
getline(cin, names);
With the cin >> number command before the getline() command however (which I'm guessing is the issue), it won't allow me to input names. Why?
I heard something about a cin.clear() command, but I have no idea how this works or why this is even necessary.
cout << "Enter the number: ";
int number;
cin >> number;
cin.ignore(256, '\n'); // remaining input characters up to the next newline character
// are ignored
cout << "Enter names: ";
string names;
getline(cin, names);
Another way of doing it is to put a
cin.ignore ( std::numeric_limits<std::streamsize>::max(), '\n' );
after your cin>>number; to flush the input buffer completely (rejecting all of the extra characters until a newline is found). You need to #include <limits> to get the max() method.
cout << "Enter the number: ";
int number;
if (cin >> number)
{
// throw away the rest of the line
char c;
while (cin.get(c) && c != '\n')
if (!std::isspace(c))
{
std::cerr << "ERROR unexpected character '" << c << "' found\n";
exit(EXIT_FAILURE);
}
cout << "Enter names: ";
string name;
// keep getting lines until EOF (or "bad" e.g. error reading redirected file)...
while (getline(cin, name))
...use name...
}
else
{
std::cerr << "ERROR reading number\n";
exit(EXIT_FAILURE);
}
In the code above, this bit...
char c;
while (cin.get(c) && c != '\n')
if (!std::isspace(c))
{
std::cerr << "ERROR unexpected character '" << c << "' found\n";
exit(EXIT_FAILURE);
}
...checks the rest of the input line after the number contains only whitespace.
Why not just use ignore?
That's pretty verbose, so using ignore on the stream after >> x is an oft-recommended alternative way to discard content through to the next newline, but it risks throwing away non-whitespace content and in doing so, overlooking corrupt data in the file. You may or may not care, depending on whether the file's content's trusted, how important it is to avoid processing corrupt data etc..
So when would you use clear and ignore?
So, std::cin.clear() (and std::cin.ignore()) isn't necessary for this, but is useful for removing error state. For example, if you want to give the user many chances to enter a valid number.
int x;
while (std::cout << "Enter a number: " &&
!(std::cin >> x))
{
if (std::cin.eof())
{
std::cerr << "ERROR unexpected EOF\n";
exit(EXIT_FAILURE);
}
std::cin.clear(); // clear bad/fail/eof flags
// have to ignore non-numeric character that caused cin >> x to
// fail or there's no chance of it working next time; for "cin" it's
// common to remove the entire suspect line and re-prompt the user for
// input.
std::cin.ignore(std::numeric_limits<std::streamsize>::max());
}
Can't it be simpler with skipws or similar?
Another simple but half-baked alternative to ignore for your original requirement is using std::skipws to skip any amount of whitespace before reading lines...
if (std::cin >> number >> std::skipws)
{
while (getline(std::cin, name))
...
...but if it gets input like "1E6" (e.g. some scientist trying to input 1,000,000 but C++ only supports that notation for floating point numbers) won't accept that, you'd end up with number set to 1, and E6 read as the first value of name. Separately, if you had a valid number followed by one or more blank lines, those lines would be silently ignored.
Try:
int number;
cin >> number;
char firstCharacterOfNames;
cin >> firstCharacterOfNames; // This will discard all leading white space.
// including new-line if there happen to be any.
cin.unget(); // Put back the first character of the name.
std::string names;
std::getline(cin, names); // Read the names;
Alternatively. If you know that number and names will always be on different lines.
cin >> number;
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::getline(cin, names);
You can use std::ws to extract any whitespace characters in the input buffer before using getline. Header for std::ws is sstream.
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
cin>>ws;
getline(cin, names);
Try cin.ignore() when you use cin before getline() function
void inputstu(){
cout << "Enter roll Number:";
cin >> roll_no;
cin.ignore(); //ignore the withspace and enter key
cout << "Enter name:";
getline(cin, stu_name);
}
Or you can flush the input buffer to read the string
fflush(stdin)
it is defined in header stdio.h.
This code works..
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
fflush(stdin); //FLUSHING STDIN
getline(cin, names);
i just used
getline(cin >> ws,lard.i_npute);
with the standard
#include <iostream>
header in the instances where I was having problems with carriage returns and the ws manipulator worked. I will probably start embedding looping functions as classes and using constructor and destructor calls atleast.
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
getline(cin, names);//works on the \n left behind
getline(cin, names);//continues and rewrites names
its pretty self explainatory, there is a \n left behind in the stream that cin >> number uses, which gets assigned to names the first time its used. Reusing the getline writes the correct value now.
You can find the answer you want in cppreference.
When used immediately after whitespace-delimited input, e.g. after int n; std::cin >> n;, getline consumes the endline character left on the input stream by operator>>, and returns immediately. A common solution is to ignore all leftover characters on the line of input with cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); before switching to line-oriented input.
you want to use cin.ignore() after your cin statements because you want to ignore the "\n" left in the buffer after taking your int variable with cin.
i have a similar program i used with a similar problem:
#include <iostream>
#include <iomanip>
#include <limits>
using namespace std;
int main() {
int i = 4;
double d = 4.0;
string s = "HackerRank ";
// Declare second integer, double, and String variables.
int n;
double d2;
string str;
// Read and save an integer, double, and String to your variables.
cin >> n;
cin >> d2;
cin.ignore();
getline(cin, str);
// Print the sum of both integer variables on a new line.
cout << i + n << endl;
// Print the sum of the double variables on a new line.
cout << d + d2 << endl;
// Concatenate and print the String variables on a new line
cout << s << str << endl;
// The 's' variable above should be printed first.
return 0;
}
Conceptually, I think you want each answer to be neatly one line. So why don't you try this?
cout << "Enter the number: ";
string line;
getline(cin, line);
int number = std::stoi(line);
cout << "Enter names: ";
string names;
getline(cin, names);
The code consumes the first newline character correctly, gives you the number if the line is correct or throws an exception if it is not. All for free!
#include <iostream>
#include <string>
using namespace std;
int main()
{
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
// USE peek() TO SOLVE IT! ;)
if (cin.peek() == '\n') {
cin.ignore(1 /*numeric_limits<streamsize>::max()*/, '\n');
}
getline(cin, names);
return 0;
}
Just peek ahead using cin.peek() and see if a '\n' is still left in cin's internal buffer. If so: ignore it (basically skip over it)

Whats the best way to split CSV key value pairs into a map [duplicate]

This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 2 years ago.
I need the following program to take the entire line of user input and put it into string names:
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
getline(cin, names);
With the cin >> number command before the getline() command however (which I'm guessing is the issue), it won't allow me to input names. Why?
I heard something about a cin.clear() command, but I have no idea how this works or why this is even necessary.
cout << "Enter the number: ";
int number;
cin >> number;
cin.ignore(256, '\n'); // remaining input characters up to the next newline character
// are ignored
cout << "Enter names: ";
string names;
getline(cin, names);
Another way of doing it is to put a
cin.ignore ( std::numeric_limits<std::streamsize>::max(), '\n' );
after your cin>>number; to flush the input buffer completely (rejecting all of the extra characters until a newline is found). You need to #include <limits> to get the max() method.
cout << "Enter the number: ";
int number;
if (cin >> number)
{
// throw away the rest of the line
char c;
while (cin.get(c) && c != '\n')
if (!std::isspace(c))
{
std::cerr << "ERROR unexpected character '" << c << "' found\n";
exit(EXIT_FAILURE);
}
cout << "Enter names: ";
string name;
// keep getting lines until EOF (or "bad" e.g. error reading redirected file)...
while (getline(cin, name))
...use name...
}
else
{
std::cerr << "ERROR reading number\n";
exit(EXIT_FAILURE);
}
In the code above, this bit...
char c;
while (cin.get(c) && c != '\n')
if (!std::isspace(c))
{
std::cerr << "ERROR unexpected character '" << c << "' found\n";
exit(EXIT_FAILURE);
}
...checks the rest of the input line after the number contains only whitespace.
Why not just use ignore?
That's pretty verbose, so using ignore on the stream after >> x is an oft-recommended alternative way to discard content through to the next newline, but it risks throwing away non-whitespace content and in doing so, overlooking corrupt data in the file. You may or may not care, depending on whether the file's content's trusted, how important it is to avoid processing corrupt data etc..
So when would you use clear and ignore?
So, std::cin.clear() (and std::cin.ignore()) isn't necessary for this, but is useful for removing error state. For example, if you want to give the user many chances to enter a valid number.
int x;
while (std::cout << "Enter a number: " &&
!(std::cin >> x))
{
if (std::cin.eof())
{
std::cerr << "ERROR unexpected EOF\n";
exit(EXIT_FAILURE);
}
std::cin.clear(); // clear bad/fail/eof flags
// have to ignore non-numeric character that caused cin >> x to
// fail or there's no chance of it working next time; for "cin" it's
// common to remove the entire suspect line and re-prompt the user for
// input.
std::cin.ignore(std::numeric_limits<std::streamsize>::max());
}
Can't it be simpler with skipws or similar?
Another simple but half-baked alternative to ignore for your original requirement is using std::skipws to skip any amount of whitespace before reading lines...
if (std::cin >> number >> std::skipws)
{
while (getline(std::cin, name))
...
...but if it gets input like "1E6" (e.g. some scientist trying to input 1,000,000 but C++ only supports that notation for floating point numbers) won't accept that, you'd end up with number set to 1, and E6 read as the first value of name. Separately, if you had a valid number followed by one or more blank lines, those lines would be silently ignored.
Try:
int number;
cin >> number;
char firstCharacterOfNames;
cin >> firstCharacterOfNames; // This will discard all leading white space.
// including new-line if there happen to be any.
cin.unget(); // Put back the first character of the name.
std::string names;
std::getline(cin, names); // Read the names;
Alternatively. If you know that number and names will always be on different lines.
cin >> number;
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::getline(cin, names);
You can use std::ws to extract any whitespace characters in the input buffer before using getline. Header for std::ws is sstream.
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
cin>>ws;
getline(cin, names);
Try cin.ignore() when you use cin before getline() function
void inputstu(){
cout << "Enter roll Number:";
cin >> roll_no;
cin.ignore(); //ignore the withspace and enter key
cout << "Enter name:";
getline(cin, stu_name);
}
Or you can flush the input buffer to read the string
fflush(stdin)
it is defined in header stdio.h.
This code works..
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
fflush(stdin); //FLUSHING STDIN
getline(cin, names);
i just used
getline(cin >> ws,lard.i_npute);
with the standard
#include <iostream>
header in the instances where I was having problems with carriage returns and the ws manipulator worked. I will probably start embedding looping functions as classes and using constructor and destructor calls atleast.
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
getline(cin, names);//works on the \n left behind
getline(cin, names);//continues and rewrites names
its pretty self explainatory, there is a \n left behind in the stream that cin >> number uses, which gets assigned to names the first time its used. Reusing the getline writes the correct value now.
You can find the answer you want in cppreference.
When used immediately after whitespace-delimited input, e.g. after int n; std::cin >> n;, getline consumes the endline character left on the input stream by operator>>, and returns immediately. A common solution is to ignore all leftover characters on the line of input with cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); before switching to line-oriented input.
you want to use cin.ignore() after your cin statements because you want to ignore the "\n" left in the buffer after taking your int variable with cin.
i have a similar program i used with a similar problem:
#include <iostream>
#include <iomanip>
#include <limits>
using namespace std;
int main() {
int i = 4;
double d = 4.0;
string s = "HackerRank ";
// Declare second integer, double, and String variables.
int n;
double d2;
string str;
// Read and save an integer, double, and String to your variables.
cin >> n;
cin >> d2;
cin.ignore();
getline(cin, str);
// Print the sum of both integer variables on a new line.
cout << i + n << endl;
// Print the sum of the double variables on a new line.
cout << d + d2 << endl;
// Concatenate and print the String variables on a new line
cout << s << str << endl;
// The 's' variable above should be printed first.
return 0;
}
Conceptually, I think you want each answer to be neatly one line. So why don't you try this?
cout << "Enter the number: ";
string line;
getline(cin, line);
int number = std::stoi(line);
cout << "Enter names: ";
string names;
getline(cin, names);
The code consumes the first newline character correctly, gives you the number if the line is correct or throws an exception if it is not. All for free!
#include <iostream>
#include <string>
using namespace std;
int main()
{
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
// USE peek() TO SOLVE IT! ;)
if (cin.peek() == '\n') {
cin.ignore(1 /*numeric_limits<streamsize>::max()*/, '\n');
}
getline(cin, names);
return 0;
}
Just peek ahead using cin.peek() and see if a '\n' is still left in cin's internal buffer. If so: ignore it (basically skip over it)

Why does the while processes one less time than expected? [duplicate]

This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 2 years ago.
I need the following program to take the entire line of user input and put it into string names:
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
getline(cin, names);
With the cin >> number command before the getline() command however (which I'm guessing is the issue), it won't allow me to input names. Why?
I heard something about a cin.clear() command, but I have no idea how this works or why this is even necessary.
cout << "Enter the number: ";
int number;
cin >> number;
cin.ignore(256, '\n'); // remaining input characters up to the next newline character
// are ignored
cout << "Enter names: ";
string names;
getline(cin, names);
Another way of doing it is to put a
cin.ignore ( std::numeric_limits<std::streamsize>::max(), '\n' );
after your cin>>number; to flush the input buffer completely (rejecting all of the extra characters until a newline is found). You need to #include <limits> to get the max() method.
cout << "Enter the number: ";
int number;
if (cin >> number)
{
// throw away the rest of the line
char c;
while (cin.get(c) && c != '\n')
if (!std::isspace(c))
{
std::cerr << "ERROR unexpected character '" << c << "' found\n";
exit(EXIT_FAILURE);
}
cout << "Enter names: ";
string name;
// keep getting lines until EOF (or "bad" e.g. error reading redirected file)...
while (getline(cin, name))
...use name...
}
else
{
std::cerr << "ERROR reading number\n";
exit(EXIT_FAILURE);
}
In the code above, this bit...
char c;
while (cin.get(c) && c != '\n')
if (!std::isspace(c))
{
std::cerr << "ERROR unexpected character '" << c << "' found\n";
exit(EXIT_FAILURE);
}
...checks the rest of the input line after the number contains only whitespace.
Why not just use ignore?
That's pretty verbose, so using ignore on the stream after >> x is an oft-recommended alternative way to discard content through to the next newline, but it risks throwing away non-whitespace content and in doing so, overlooking corrupt data in the file. You may or may not care, depending on whether the file's content's trusted, how important it is to avoid processing corrupt data etc..
So when would you use clear and ignore?
So, std::cin.clear() (and std::cin.ignore()) isn't necessary for this, but is useful for removing error state. For example, if you want to give the user many chances to enter a valid number.
int x;
while (std::cout << "Enter a number: " &&
!(std::cin >> x))
{
if (std::cin.eof())
{
std::cerr << "ERROR unexpected EOF\n";
exit(EXIT_FAILURE);
}
std::cin.clear(); // clear bad/fail/eof flags
// have to ignore non-numeric character that caused cin >> x to
// fail or there's no chance of it working next time; for "cin" it's
// common to remove the entire suspect line and re-prompt the user for
// input.
std::cin.ignore(std::numeric_limits<std::streamsize>::max());
}
Can't it be simpler with skipws or similar?
Another simple but half-baked alternative to ignore for your original requirement is using std::skipws to skip any amount of whitespace before reading lines...
if (std::cin >> number >> std::skipws)
{
while (getline(std::cin, name))
...
...but if it gets input like "1E6" (e.g. some scientist trying to input 1,000,000 but C++ only supports that notation for floating point numbers) won't accept that, you'd end up with number set to 1, and E6 read as the first value of name. Separately, if you had a valid number followed by one or more blank lines, those lines would be silently ignored.
Try:
int number;
cin >> number;
char firstCharacterOfNames;
cin >> firstCharacterOfNames; // This will discard all leading white space.
// including new-line if there happen to be any.
cin.unget(); // Put back the first character of the name.
std::string names;
std::getline(cin, names); // Read the names;
Alternatively. If you know that number and names will always be on different lines.
cin >> number;
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::getline(cin, names);
You can use std::ws to extract any whitespace characters in the input buffer before using getline. Header for std::ws is sstream.
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
cin>>ws;
getline(cin, names);
Try cin.ignore() when you use cin before getline() function
void inputstu(){
cout << "Enter roll Number:";
cin >> roll_no;
cin.ignore(); //ignore the withspace and enter key
cout << "Enter name:";
getline(cin, stu_name);
}
Or you can flush the input buffer to read the string
fflush(stdin)
it is defined in header stdio.h.
This code works..
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
fflush(stdin); //FLUSHING STDIN
getline(cin, names);
i just used
getline(cin >> ws,lard.i_npute);
with the standard
#include <iostream>
header in the instances where I was having problems with carriage returns and the ws manipulator worked. I will probably start embedding looping functions as classes and using constructor and destructor calls atleast.
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
getline(cin, names);//works on the \n left behind
getline(cin, names);//continues and rewrites names
its pretty self explainatory, there is a \n left behind in the stream that cin >> number uses, which gets assigned to names the first time its used. Reusing the getline writes the correct value now.
You can find the answer you want in cppreference.
When used immediately after whitespace-delimited input, e.g. after int n; std::cin >> n;, getline consumes the endline character left on the input stream by operator>>, and returns immediately. A common solution is to ignore all leftover characters on the line of input with cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); before switching to line-oriented input.
you want to use cin.ignore() after your cin statements because you want to ignore the "\n" left in the buffer after taking your int variable with cin.
i have a similar program i used with a similar problem:
#include <iostream>
#include <iomanip>
#include <limits>
using namespace std;
int main() {
int i = 4;
double d = 4.0;
string s = "HackerRank ";
// Declare second integer, double, and String variables.
int n;
double d2;
string str;
// Read and save an integer, double, and String to your variables.
cin >> n;
cin >> d2;
cin.ignore();
getline(cin, str);
// Print the sum of both integer variables on a new line.
cout << i + n << endl;
// Print the sum of the double variables on a new line.
cout << d + d2 << endl;
// Concatenate and print the String variables on a new line
cout << s << str << endl;
// The 's' variable above should be printed first.
return 0;
}
Conceptually, I think you want each answer to be neatly one line. So why don't you try this?
cout << "Enter the number: ";
string line;
getline(cin, line);
int number = std::stoi(line);
cout << "Enter names: ";
string names;
getline(cin, names);
The code consumes the first newline character correctly, gives you the number if the line is correct or throws an exception if it is not. All for free!
#include <iostream>
#include <string>
using namespace std;
int main()
{
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
// USE peek() TO SOLVE IT! ;)
if (cin.peek() == '\n') {
cin.ignore(1 /*numeric_limits<streamsize>::max()*/, '\n');
}
getline(cin, names);
return 0;
}
Just peek ahead using cin.peek() and see if a '\n' is still left in cin's internal buffer. If so: ignore it (basically skip over it)

C++ - Sanitize Integer Whole Number Input

I currently am using a function I found in another StackOverflow post(I can't find it), that I am using before, named "GetInt". My issue with it is that if the user inputs something like "2 2 2" it puts it into my next two Cin's. I have tried getLine, but it requires a string and I am looking for an int value. How would I structure a check to sanitize for an integer value greater than 2 and throw an error to the 2 2 2 answer.
#include <iostream>
#include <string>
#include <sstream>
#include "Board.cpp"
#include "Player.cpp"
using namespace std;
int getInt()
{
int x = 0;
while (!( cin >> x))
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Please input a proper 'whole' number: " << endl;
}
return (x);
}
and my call
do
{
//do
//{
cout << "How many players are there? \n";
numberOfPlayers = getInt();
//} while (isdigit(numberOfPlayers) == false);
} while (numberOfPlayers < 2);
EDIT:
I chose Justin's answer because it was the closest to my original code and solved the issue without major changes.
Integers are delimited by spaces and the input 2 2 2 is just multiple integers. If you want to make sure that just one integer is entered per line you could skip whitespace characters until a newline is found. If a non-whitespace is found prior to a newline you could issue an error:
numberOfPlayers = getInt();
int c;
while (std::isspace(c = std::cin.peek()) && c != '\n') {
std::cin.ignore();
}
if (c != std::char_traits<char>::eof() && c != '\n') {
// deal with additional input on the same line here
}
You were on the right track with std::getline. You read the whole line as a string, then put it into a std::istringstream and read the integer out.
std::string line;
if( std::getline(cin, line) ) {
std::istringstream iss(line);
int x;
if( iss >> x ) return x;
}
// Error
This will have the effect of discarding any fluff that comes after the integer. It will only error if there is no input or no integer could be read.
If you want to have an error when stuff appears after the integer, you could take advantage of the way strings are read from a stream. Any whitespace is okay, but anything else is an error:
std::istringstream iss(line);
int x;
if( iss >> x ) {
std::string fluff;
if( iss >> fluff ) {
// Error
} else {
return x;
}
}
Change your code to this:
int getInt()
{
int x = 0;
while (!( cin >> x))
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Please input a proper 'whole' number: " << endl;
}
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
return (x);
}
Your code to ignore the rest of the line after receiving the integer is only called if the integer collection fails (for example, you type "h" as the number of players).