This question already has answers here:
How to test whether stringstream operator>> has parsed a bad type and skip it
(5 answers)
Closed 2 years ago.
Im a new user of c++ and I am stuck with a problem.
If the input for the int variable 'x' is anything other than a number, then c++ seems to skip the cin associated with the char variable 'y'. I tried to use cin.ignore and cin.clear, but they dont seem to work. Any ideas on how to make the program still ask the value for char 'y' when the value for int 'x' is anything but a number(eg. 'a' '*' '') ?
#include <iostream>
using namespace std;
int main()
{
int x;
char y;
cout << "num: ";
cin >> x;//int input
cout << endl;//blank line
cout << "char: ";
cin >> y;//char input
cout << endl;//blank line
return 0;
}
Are you passing parameters to ignore?
The first parameter is the maximum of chars to be ignored and the second one is the flag that it should stop ignoring after findind it (which in the example below I've put '\n')
cin.clear();
cin.ignore(1000, '\n');
To summarize, the code says: Clear up to 1000 chars or up to the first '\n'.
Related
This question already has answers here:
Integer validation for input
(3 answers)
Closed 6 years ago.
For example I have the code:
#include <iostream>
using namespace std;
int main()
{
int test = 0;
cout << "Please input a number:";
while(!(cin >> test))
{
cout << "Invalid input";
}
if(test == 1)
{
cout << "Test is 1";
}
else
{
// Do something
}
return 0;
}
If I input 1abc to the test variable it still continues to process the if statement even though the input is wrong. How could I ignore all the input made and just accept pure numbers in it?
You can use getline, find_if_not, and isdigit to check if an entire line is a valid integer or not. This will loop until it reads an integer:
std::string number;
while (std::getline(std::cin, number) && number.end() !=
std::find_if_not(number.begin(), number.end(), &isdigit))
std::cout << "gitgud!";
getline will read the input up to the newline, and put it in the string. find_if_not and isdigit will find the first non-digit character. If there are none (meaning it is a valid integer), it will return the end iterator.
This question already has answers here:
Integer validation for input
(3 answers)
Closed 6 years ago.
For example I have the code:
#include <iostream>
using namespace std;
int main()
{
int test = 0;
cout << "Please input a number:";
while(!(cin >> test))
{
cout << "Invalid input";
}
if(test == 1)
{
cout << "Test is 1";
}
else
{
// Do something
}
return 0;
}
If I input 1abc to the test variable it still continues to process the if statement even though the input is wrong. How could I ignore all the input made and just accept pure numbers in it?
You can use getline, find_if_not, and isdigit to check if an entire line is a valid integer or not. This will loop until it reads an integer:
std::string number;
while (std::getline(std::cin, number) && number.end() !=
std::find_if_not(number.begin(), number.end(), &isdigit))
std::cout << "gitgud!";
getline will read the input up to the newline, and put it in the string. find_if_not and isdigit will find the first non-digit character. If there are none (meaning it is a valid integer), it will return the end iterator.
This question already has answers here:
Using fflush(stdin)
(7 answers)
Closed 3 years ago.
I wrote this simple addition software, in which I wanted the addition to end when the user entered 'n'. My current code works just fine. But I made two more variations of the same code, one worked, and one gave me an error. Can anyone tell me what is happening exactly in each case?
int a, b=0;
cout<<"Welcome to my Addition Software!!\n\n";
do{
cin>>a;
b+=a;
}while(getchar()!='n');
cout<<b;
//works just fine
int a, b=0;
cout<<"Welcome to my Addition Software!!\n\n";
do{
fflush(stdin);
cin>>a;
b+=a;
}while(getchar()!='n');
cout<<b;
//this one works too
int a, b=0;
cout<<"Welcome to my Addition Software!!\n\n";
do{
a=getchar();
b+=a;
}while(a!='n');
cout<<b;
//doesn't work
I wanna know why fflush(stdin) have no effect on the code. If I just keep writing my input like "20, 30, 50, n" instead of "20, y, 30, y, 50, n" I get the same result in both working codes. Why does this happen?
First of all, it is best to use C++ standard input and output std::cin and std::cout respectively.
The main problem with your code is that it conflicts with types you want:
You want to add integers int together and to see if the input is the character char 'n'.
What's happening is the legacy C fflush(stdin) "flushes" or clears the standard input stream buffer (read more here: https://www.google.com/amp/s/www.geeksforgeeks.org/use-fflushstdin-c/amp/) and getchar() receives character input from the user. getchar() returns a character and by deduction, your code transmutes that input into its integral int ASCII-ANSI numerical integral equivalent.
This means that on the third version, when you input "30", what actually is collected is '3' and without flushing the buffer, the next input is considered '0' causing a problem.
I suggest you use a control structure to check if the user wants to continue before receiving input to add:
int a = 0, b =0;
char c = 0; // for y/n responses
std::cout << "Welcome to my ... "; //just finish this string
do{
std::cout << "input integer: "; // for better formatting leave at least one space after the colon
std::cin >> a;
b += a;
std::cout << "Continue? n to stop: "
std::cin >> c;
} while (c != 'n')
std::cout << "Added: " << b;
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:
How to make cin take only numbers
(2 answers)
Closed 6 years ago.
I have the following code:
#include <iostream>
#include <limits>
#include <locale>
using namespace std;
int main(int argc, char** argv) {
setlocale(LC_ALL, "English");
int i, vetor[16];
for(i = 0; i < 16; i ++) {
cout << "Input the position: [" << i << "]: ";
cin >> vetor[i];
if(cin.fail()) {
cin.clear();
cin.ignore(numeric_limits < streamsize > ::max(), '\n');
cout << "Please, input only numbers." << endl;
i --;
continue;
}
if(vetor[i] <= 0) {
cout << "Insert a non-zero value." << endl;
i --;
continue;
}
}
cout << vetor[0];
return 0;
}
And I need to accept only numbers. When I run it and insert "1" (or any other number), it goes to the following position, what's correct. When I input "a", it shows me the error and warn me to input only numbers, what's correct too. If I input "a1", the same thing occurs, what's correct. But when I input "1a", it shows me the warning, but the code continues to the next position, and when it executes the last line with the cout command above the return, it tells me the value is "1", not "1a", because the type of the variable is int I believe.
Can someone tells me why does it happen? I need to accept only numbers, and "1a" is not a number. How can I filter this and how can I do to when I input "1a", occurs the same thing as I had input "a"?
I use DevC++ 5.11.
It happens because cin extracts the 1 digit in one pass, and stores that in your array. It stops reading when it encounters the a (since that is not a valid character for an integer), and leaves it in the input buffer. It then reads the a on the next pass, which causes it to fail because it's not an integer.
What you should do is use std::getline to read strings instead. Then you can do any kind of parsing you want. You can use functions from the standard library like std::stoi if they suit you. Otherwise write your own custom parsing.