Bug when user input more than a character with char variable - c++

i'm making simple program to show "True" if user input 'z' and show "False" if user input anything else.
However, the problem is when user input more than a character, such as when user input 'zz' the output is
True
Input : True
and when user input such as 'zs' which should be wrong, the output is
True
Input : Wrong
Here's my code
#include <iostream>
using namespace std;
int main()
{
char input;
cout << "Check input" << endl;
while(true){
cout << "Input : ";
cin >> input;
if(input=='z'){
cout << "True" << endl;
} else {
cout << "Wrong" << endl;
}
}
return 0;
}
I wonder if there are ways to prevent this without change variable type to string?
I use CodeBlocks 16.04 (MinGW) with GNU GCC Compiler on Windows 10 x64

You cannot do that by reading single chars. The point is that if the user enters e.g. zz he actually did enter those two chars and these are the chars you are getting when you read from cin.
Just read a std::string as suggested and check only the first character of the string. That's just as simple that what you're doing.
So you probably want this:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string input;
cout << "Check input" << endl;
while (true) {
cout << "Input : ";
cin >> input;
if (input.length() > 0 && input[0] == 'z') {
cout << "True" << endl;
}
else {
cout << "Wrong" << endl;
}
}
return 0;
}

Its definitely possible you just have to check the first character and make sure It is the only character entered than flush the buffer to get rid of the rest of the string.
code:
#include <iostream>
#include <string>
using namespace std;
int main()
{
char input;
cout << "Check input" << endl;
while (true) {
cout << "Input : ";
cin >> input;
//Check if the input is z and there is only 1 character inputted
if (cin.rdbuf()->in_avail() == 1 && input == 'z') {
cout << "True" << endl;
}
else {
cout << "Wrong" << endl;
}
//Flush the buffer
cin.clear();
cin.ignore(INT_MAX, '\n');
}
return 0;
}

Related

ifstream usage and user input not outputting content to read

I'm practicing ifstream usage. I want the user to enter the file they want to read, in this example num1.txt specifically. I want the console to read one letter from num1.txt and output it on its own line.
I've ran the code below, and after entering "num1.txt" into the console, I get nothing back. I've tried moving around cout << num << endl; to the inner do statement, but it ends up repeating the number 10 an infinite amount.
What am I doing wrong here?
Contents in num1.txt:
2 4 6 8 10
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main() {
string fileName, cont;
ifstream inputFile;
do {
int num = 0;
int total = 0;
cout << "Please enter the file name: ";
cin >> fileName;
inputFile.open(fileName);
if (inputFile.is_open()) {
do {
inputFile >> num;
total += num;
}
while(num > 0);
if (total != 0) {
cout << num << endl;
cout << "Total is: " << total << endl;
}
}
else {
cout << "Failed to open file." << endl;
}
inputFile.close();
cout << "Do you want to continue processing files? (yes or no): " << endl;
cin >> cont;
}
while (cont == "yes");
}
Your inner do loop is not correctly validating that operator>> is actually successful before using num. It should be looking at the stream's error state after each read. The easiest way to do that is to change your do loop into a while loop that uses the result of the read as its loop condition, eg:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main() {
string fileName, cont;
ifstream inputFile;
do {
cout << "Please enter the file name: ";
cin >> fileName;
inputFile.open(fileName);
if (inputFile.is_open()) {
int num = 0;
int total = 0;
while (inputFile >> num) {
total += num;
}
inputFile.close();
cout << "Total is: " << total << endl;
}
else {
cout << "Failed to open file." << endl;
}
cout << "Do you want to continue processing files? (yes or no): " << endl;
}
while ((cin >> cont) && (cont == "yes"));
return 0;
}

C++ I/O stream issue: program asks for input twice or work incorrectly

I'm trying to write a program that reads input as int from the command line, and if the user enters an int, program prints "Input is " + the number if users enter an incorrect type input, output "wrong input".
Here is my code:
#include <iostream>
#include <string>
using namespace std;
int main() {
int input;
cout << "Enter an Int:" << endl;
cin >> input;
if (!(cin >> input)) {
cout << "wrong format input" << endl;
return 1;
}
cout << "input is " << input << endl;
return 0;
}
Now with cin >> input; (case-1) program asks for twice input when enter correct integer; it prints "wrong format input" if user enter '2.2' or 'a'.
Without cin >> input; (case-2) program ask for once input when enter correct integer; but it prints "input is 2" when user enter '2.2', instead of printing "wrong" message, program prints "Input is 2".
Which part in my code did I make mistake? How can I fix this?
For case-2:
Here is the sample that allows to enter several integers on the same line, but disallows anything else
#include <iostream>
#include <string>
int main()
{
std::string input;
while(std::cin >> input){
size_t last;
int res;
bool good = true;
try{
res = std::stoi(input,&last);
}
catch(...){
good = false;
}
if(!good || last != input.length()){
std::cout << "Incorrect input: " << input << ", try again.\n";
}
else{
std::cout << "Integer read: " << res << '\n';
}
}
return 0;
}
/***************
Output
$ ./test
2
Integer read: 2
hello
Incorrect input: hello, try again.
2.2
Incorrect input: 2.2, try again.
1111111111111111111111111111111111111111111111111111111111111111111111
Incorrect input: 1111111111111111111111111111111111111111111111111111111111111111111111, try again.
3 4
Integer read: 3
Integer read: 4
^Z
[3]+ Stopped ./test
*/
Another version - using stringstream
while(std::cin >> input){
std::istringstream ss(input);
int res;
ss >> res;
if(!ss){
std::cout << "Incorrect input: " << input << ", try again.\n";
}
else{
char ch = ss.get();//let's check that no more characters left in the string
if(!ss){
std::cout << "Integer read: " << res << '\n';
}
else{
std::cout << "Incorrect input: " << input << ", try again.\n";
}
}
}
if(!(cin >> input)) is the reason for the second input. Just do this:
#include <iostream>
#include <string>
using namespace std;
int main() {
int input;
cout << "Enter an Int:" << endl;
cin >> input;
if (cin.fail()) {
cout << "wrong format input" << endl;
return 1;
}
cout << "input is " << input << endl;
return 0;
}

Unknown behavior from cin

First off I'd like to say I know that using getline is a better alternative, however, i am curious as to why this code doesn't work as intended: and I can't figure out why
#include <iostream>
#include <string>
using namespace std;
int main() {
while(1) {
int input;
cout << "---> ";
cin >> input;
if(cin.fail()) {
char rd = cin.get();
cout << "failure" << rd << "=" << cin.fail() << " " << endl;
}
}
return 0;
}
Intended: if an integer is entered, continue otherwise cin fails, we pull one char from stdin and essentially output it. Then we keep looping.
The way I see it, eventually cin.get() should clear up bad input; but it never does: it gets stuck in an infintie loop. What?
cin.fail() detects whether the value entered fits the value defined in the variable.
But if cin.fail() is true, it means that
a) the entered value does not fit the variable
b) the varialbe will not be affected
c) the instream is still broken
d) the entered value is still in the buffer and will be used for the next "cin >> variable"statement.
Hence you have to do the following:
a) repair the instream via cin.clear();
b) clear the buffer with cin.ignore(std::numeric_limits::max(),'\n');
#include <iostream>
#include <string>
using namespace std;
int main() {
while(1) {
int input;
cout << "---> ";
cin >> input;
if(cin.fail()) {
char rd = cin.get();
cout << "failure" << rd << "=" << cin.fail() << " " << endl;
cin.clear();
cin.ignore();
}
}
return 0;
}
After taking the input integer, it gets a newline as a character when you press enter. Same as for character input
#include <iostream>
#include <string>
using namespace std;
int main() {
while(1) {
int input;
cout << "---> ";
cin >> input;
getchar();
if(cin.fail()) {
char rd = cin.get();
getchar();
cout << "failure" << rd << "=" << cin.fail() << " " << endl;
}
}
return 0;
}

Prompt user for positive number, and continues to prompt the user until they enter a positive number c++

//review3
#include <iostream>
#include <cstdlib>
#include <string>
#include <fstream>
using namespace std;
int number;
int main()
{
cout << "Enter a positive number" << endl;
cin >> number;
while (number < 0)
{
cout << "Enter a positive number" << endl;
}
if (number > 0)
{
cout << "Awesome job!" << endl;
}
return 0;
}
This is my code so far. I started with an else if but if the user entered a negative number the program would simply close. I changed this to a while loop and got stuck in an infinite loop. Before I had an if and else if statement. I need to continue to prompt the user until they enter a positive number in c++.
Your while() loop doesn't continue to prompt for input, that's why you're getting an infinite loop - because number never changes!
You can put the input operation into the while() loop like this:
while (cin >> number && number < 0)
{
cout << "Enter a positive number: " << endl;
}
if (cin)
{
cout << "Awesome job" << endl;
}
Thus, during each iteration of the loop the user will be prompted for input.
We check the state of cin afterwards to make sure that the above loop didn't stop because of invalid input (or no input at all).
#include <iostream>
using namespace std;
int number;
int main()
{
cout << "Enter a positive number" << endl;
cin >> number;
if (number < 0) {
cout << "Enter a positive number" << endl;
}
else {
cout << "Awesome job!" << endl;
}
return 0;
}
You can check if you get number or string here
sure in this case you should get input to string variable. If you want to convert it to integer you can use std::stoi
#include <iostream>
#include <string>
#include <cstring>
int main()
{
while(true)
{
std::cout << "Pleaase enter a positive number." << std::endl;
std::string buf;
int x = -255;
std::cin >> buf;
x = std::atoi(buf.c_str());
if(x > 0)
{
break;
}
}
std::cout << "Awesome Job!" << std::endl;
}
You can also do this snippet . Use #include <ctype.h> or <cctype>
while(1){
cin>>number;
if(number<0 || isalpha(number)) return 0;
cout<<"Awesome Job";
}

C++ input validation for numeric input

I'm creating my own very simple program that allows the user to input a numeric value. At the moment the code works just fine, but I need a validation if else statement. This is what I have at the moment;
#include <iostream>
#include <string>
using namespace std;
int main()
{
unsigned __int64 input = 0;
char str[] = "qwertyuiopasdfghjklzxcvbnm[]{};'#:#~,./<>?|!£$%^&*()";
cout << "Insert a number" << endl;
cin >> input;
if (input % 2 == 0)
{
cout << "Even!" << endl;
}
else
{
if (input% 2 == 1)
{
cout << "Odd" << endl;
cout << "Lets make it even shall we? " << "Your new number is... " << input + 1 << endl;
}
else if (isdigit(str[0]))
{
cout << "That isn't a number!" << endl;
}
}
system("pause");
return 0;
}
The issue I am having is that if the user inputs anything that isn't a number, the value it returns is "Even".
I hope you guys and girls can help!
John
Don't use token extraction (>>) for primary parsing. Once the extraction fails, your primary input is left in an unspecified state, which is terrible. Instead, read the input line by line and then process each line.
Also, never ignore the result of an input operation. That's just a flat error.
So, putting all this together, here's how you could handle this:
#include <iostream>
#include <sstream>
#include <string>
int main()
{
for (std::string line; std::cout << "Input: " && std::getline(std::cin, line); )
{
std::cout << "We're parsing your line '" << line << "'\n";
int n;
std::istringstream iss(line);
if (iss >> n >> std::ws && iss.get() == EOF)
{
std::cout << "It was a number: " << n << "\n";
}
else if (line.empty())
{
std::cout << "You didn't say anything!\n";
}
else
{
std::cout << "We could not parse '" << line << "' as a number.\n";
}
}
std::cout << "Goodbye!\n";
}
Note that all input operations (namely >> and getline) appear in immediate boolean contexts!