Unknown behavior from cin - c++

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;
}

Related

How do you test if an input is a number

I am having trouble determining if an input is a letter or a number.
If I enter anything it always says that it is not a number, what am I doing wrong.
Here is my code:
#include <iostream>
#include <unistd.h>
#include <ctype.h>
using namespace std;
int main()
{
int input = 0;
cout << "Enter a number \n";
cout << "input: ";
cin >> input;
if (isdigit(input)) {
cout << "Your number is: " << input;
}
else {
cout << "This is not a number \n";
}
//wait for ten seconds
usleep(10000000);
}
Since isdigit() expects an ASCII value as its argument, it will return true only if you type in a number between 48 (aka the ASCII code for "0") and 57 (aka the ASCII code for "9"), which isn't what you want.
In order to get the behavior you want, you'll need to read the user's input into a string, and then analyze the contents of the string to see if they reasonably represent an integer or not. Something like this:
#include <iostream>
#include <string>
#include <unistd.h>
#include <ctype.h>
using namespace std;
int main()
{
string inputStr;
cout << "Enter a number \n";
cout << "input: ";
cin >> inputStr;
// Assume a string counts as representing an integer
// if the first character of the string is an ASCII digit.
// (You might also want to accept strings where the
// first character is a + or - symbol and is immediately
// followed by an ASCII digit, but for simplicity I'm
// omitting that logic here)
if ((inputStr.length()>0)&&((isdigit(inputStr[0])))) {
int number = stoi(inputStr);
cout << "Your number is: " << number << endl;
}
else {
cout << "[" << inputStr << "] is not a number" << endl;
}
//wait for ten seconds
usleep(10000000);
}
Agree on Jeremy, I would like to add https://stackoverflow.com/a/5655685/7637661 for reference.
TLDR
#include <iostream>
using namespace std;
int main() {
int input = 0;
cout << "Enter a number \n";
cout << "input: ";
cin >> input;
if(!cin) // or if(cin.fail())
{
// user didn't input a number
cin.clear(); // reset failbit
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); //skip bad input
// next, request user reinput
cout << "This is not a number " << endl;
}
cout << "Your number is: " << input;
}

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;
}

No match for ‘operator<<’ in std

I just started learning C++, and this test seemed like a good idea so i tried doing it, doesn't seem to work, and it really doesn't make sense why (to me).
#include <iostream>
using namespace std;
int myNum = 5; // Integer (whole number without decimals)
double myFloatNum = 5.32543; // Floating point number (with decimals)
char myLetter = 'H'; // Character
string myText = "test text: test"; // String (text)
bool myBoolean = true; // Boolean (true or false)
int main() {
cout << myNum << endl;
cin >> myNum >> endl;
cout << myFloatNum << endl;
cin >> myFloatNum >> endl;
cout << myLetter << endl;
cin >> myLetter >> endl;
cout << myText << endl;
cin >> myText >> endl;
cout << myBoolean << endl;
cin >> myBoolean >> endl;
return 0;
}
You forgot to include <string>, string isn't a basic C++ datatype; use #include <string> after iostream, without the spaces after the greater than and less than signs.
It does not make sense to cin something into endl. cin is a stream to get data from, but the endl is a thing to end the line, as #arsdever commented.
Simply remove it, and your code will compile:
#include <iostream>
#include <string> // You forgot to include that header, for using std::string
using namespace std;
int myNum = 5;
double myFloatNum = 5.32543;
char myLetter = 'H';
string myText = "test text: test";
bool myBoolean = true;
int main() {
cout << myNum << endl;
cin >> myNum;
cout << myFloatNum << endl;
cin >> myFloatNum;
cout << myLetter << endl;
cin >> myLetter;
cout << myText << endl;
cin >> myText;
cout << myBoolean << endl;
cin >> myBoolean;
return 0;
}
Although, you may want to first read the user's input, and then print it. Now, you print the predefined by you value of the variable (and then print an end of line), and then read the input from the user for that specific variable.

Bug when user input more than a character with char variable

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;
}

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";
}