#include<iostream>;
int main()
{
int a = 1;
int b = 2;
std::cin >> a >> b;
std::cout << a << "+" << b << "=" << a+b << std::endl;
return 0;
}
when I enter 3 4 as input,the output will be 3+4=7,well,it's strange;
But when I enter a b,the output is 0+0=0(Why it is 0 and 0?);
The most confusing,a 4,it will be 0+0=0(Why not '0+4=4'?????);
Then i write another prog.
#include<iostream>;
int main()
{
int a = 1;
int b = 2;
std::cin >> a;
std::cin.clear();
std::cin >> b;
std::cout << a << "+" << b << "=" << a+b << std::endl;
return 0;
}
When i enter a 4,why is it still 0+0=0?Shouldn't it be 0+4=4?
Thanks to all the warm-hearted!!
I write prog3,to test what will happen when i don't write int a=1;int b=2;
2
#include <iostream>
using namespace std;
int main()
{
int a,b;
cin >> a ;
cin >> b;
cout<< a << "+"<< b <<"="<< a+b << endl;
return 0;
}
When a bagain,it outputs 0+-1218170892=-1218170892(Why isn't 0+0=0??)
Like all istreams, std::cin has error bits. These bits are set when errors occur. For example, you can find the values of the error bits with functions like good(), bad(), eof(), etc. If you read bad input (fail() returns true), use clear() to clear the flags. You will also likely need an ignore(1); to remove the offending character.
See the State functions section for more information. http://en.cppreference.com/w/cpp/io/basic_ios
The value is set to zero on an error as per C++11: If extraction fails, zero is written to value and failbit is set.
On the 'a 4' example, both values are 0 because the buffer has not been flush/cleared, so the second cin read is still reading the error, and also receives a value of 0.
std::cin is an istream instance and thus it maintains its error state when it reads something invalid.
In order to "cure" it you must both clear its flag
std::cin.clear();
and flush its buffer.
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
What is more surprising though is that it doesn't return 1 + 2 = 3 when you input invalid characters, as I would expect a failing cin stream to have no side effects on what it is trying to update.
Related
#include<iostream>;
int main()
{
int a = 1;
int b = 2;
std::cin >> a >> b;
std::cout << a << "+" << b << "=" << a+b << std::endl;
return 0;
}
when I enter 3 4 as input,the output will be 3+4=7,well,it's strange;
But when I enter a b,the output is 0+0=0(Why it is 0 and 0?);
The most confusing,a 4,it will be 0+0=0(Why not '0+4=4'?????);
Then i write another prog.
#include<iostream>;
int main()
{
int a = 1;
int b = 2;
std::cin >> a;
std::cin.clear();
std::cin >> b;
std::cout << a << "+" << b << "=" << a+b << std::endl;
return 0;
}
When i enter a 4,why is it still 0+0=0?Shouldn't it be 0+4=4?
Thanks to all the warm-hearted!!
I write prog3,to test what will happen when i don't write int a=1;int b=2;
2
#include <iostream>
using namespace std;
int main()
{
int a,b;
cin >> a ;
cin >> b;
cout<< a << "+"<< b <<"="<< a+b << endl;
return 0;
}
When a bagain,it outputs 0+-1218170892=-1218170892(Why isn't 0+0=0??)
Like all istreams, std::cin has error bits. These bits are set when errors occur. For example, you can find the values of the error bits with functions like good(), bad(), eof(), etc. If you read bad input (fail() returns true), use clear() to clear the flags. You will also likely need an ignore(1); to remove the offending character.
See the State functions section for more information. http://en.cppreference.com/w/cpp/io/basic_ios
The value is set to zero on an error as per C++11: If extraction fails, zero is written to value and failbit is set.
On the 'a 4' example, both values are 0 because the buffer has not been flush/cleared, so the second cin read is still reading the error, and also receives a value of 0.
std::cin is an istream instance and thus it maintains its error state when it reads something invalid.
In order to "cure" it you must both clear its flag
std::cin.clear();
and flush its buffer.
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
What is more surprising though is that it doesn't return 1 + 2 = 3 when you input invalid characters, as I would expect a failing cin stream to have no side effects on what it is trying to update.
my program is a calculator that currently only does addition and subtraction, but when i input a large number it starts flashing and scrolling. it works fine for small numbers. the program isn't long so here it is. a youtube video of the problem https://youtu.be/Fa03WtgXoek
#include <iostream>
int GVFU()
{
std::cout <<"enter number";
int a;
std::cin >> a;
return a;
}
int add()
{
int x = GVFU();
int y = GVFU();
int z = x + y;
std::cout <<z <<std::endl;
return 0;
}
int subtract()
{
int x = GVFU();
int y = GVFU();
int z = x - y;
std::cout <<z << std::endl;
return 0;
}
int main()
{
for ( ; ; )
{
std::cout << "enter 1 for addition and 2 for subtraction";
int c;
std::cin >> c;
if (c==1)
{
add();
}
if (c==2)
{
subtract();
}
std::cout << "press 1 to end";
int e;
std::cin >>e;
if (e==1)
{
return 0;
}
}
}
If you try to read a value from cin and the value read doesn't match the expected format, it causes the stream to fail and all future read operations will instantly return without reading anything.
Independently, in C++ integer values for the int type have a minimum and maximum possible value that depends on what compiler and system you're using. If you exceed that value when entering a number, cin will consider it a failed read.
Putting this together, once you enter a value that's too large, the program will keep running through the main loop in your program, prompting for a value, instantly returning without actually getting user input, then calculating garbage values.
To fix this, you'll need to either (1) just hope the user doesn't type in anything unexpected or (2) get user input more robustly. There are a number of good explanations about how to do option (2) here on Stack Overflow, and now that you know what the root cause of the issue is you can hopefully get the code fixed and working!
Use
std::cout << std::numeric_limits<int>::max() << std::endl;
and include #include <limits> and you will find out max int value on your machine.
int on your system is likely a 32-bit signed two's complement number, which means the max value it can represent is 2,147,483,647.
If you add bigger number stream will fail and all next read operations will return without reading anything.
Use unsigned long long which will allow you to insert bigger numbers.
You are taking your inputs as " int " and value range for int is between -2,147,483,648 to 2,147,483,647.
Which means that if you exceed this value 2,147,483,647 it can not be stored as an integer(int) type.
You should probably use Long data type for such large numbers.
You can add a following check in your code if the user input more than int limit
int GVFU()
{
std::cout <<"enter number";
int a;
std::cin >> a;
if(cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid input " << endl;
}
return a;
}
I would also add exit if invalid number
#include <iostream>
#include <cstdlib>
using namespace std;
int GVFU()
{
std::cout <<"enter number";
int a;
std::cin >> a;
if(cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid input " << endl;
std::exit(EXIT_FAILURE);
}
return a;
}
Note: You could also more info instead of just "Invalid input "
Output like size or limit info
enter 1 for addition and 2 for subtraction1
enter number4535245242
Invalid input
Program ended with exit code: 1
I want to create a program that when a user inputs something that I didn't define, the program prompts him again.
I did it with if statements but it only loops for 1 time and doesn't do it again. I tried loops but whenever the input is false it just breaks the condition and refuses all inputs alike. In c++.
Any help is much appreciated.
#include <iostream>
#include <string>
using namespace std;
void xD(){string x;
do{cout << "Retry\n";
cin >> x;}while(true);}
//declaring a function to make the shop
void shop(){
string x;
float coins = 500;
float bow_cost = 200;
cout << "welcome to the shop\n";
cout << "Bow(bow)costs 150 coins.\n";
cin >> x;
// if u chose bow you get this and get to choose again
if (x == "bow"){
cout << "you bought the bow.\n you now have " <<coins - bow_cost << " coins." << endl; cin >> x;}
/*now the problem that whenever I excute the code and type something other than bow it gives me the cin only once more and then fails even if I type bow in the 2nd attempt*/
//in my desperate 5k attempt, I tried creating a function for it.. no use.
//i want it o keep prompting me for input till i type "bow" and the other block excutes. but it never happens.
else{xD();}
}
int main(){
string name;
string i;
cout << "if you wish to visit the shop type \"shop\"\n";
cin >> i;
if(i == "shop"){shop();}
else{cin >> i;}
return 0;
}
The problem lies on the condition in this loop block
void xD(){
string x;
do{
cout << "Retry\n";
cin >> x;
}while(true);
}
The while(true) condition makes it loops forever regardless of the input. To fix this, you can change the condition:
void xD(){
string x;
do{
cout << "Retry\n";
cin >> x;
}while(x!="bow");
cout << "you bought the bow. and some other messages"<<endl;
}
That should work. However, it is still too complicated for me. This can be simplified into the snippet below:
void shop(){
string x;
float coins = 500;
float bow_cost = 200;
cout << "welcome to the shop\n";
cout << "Bow(bow)costs 150 coins.\n";
cin >> x;
while (x!="bow"){
cout << "Retry\n";
cin>>x;
}
cout << "you bought the bow.\n you now have " <<coins - bow_cost << " coins." << endl; cin >> x;
}
Instead of doing this approach (which is checking the condition only once):
if (x == "bow"){
cout << "you bought the bow.\n you now have " <<coins - bow_cost << "
coins." << endl; cin >> x;
} else{
xD();
}
which is actually a RECURSIVE invocation to the method xD()
you should do a do-while loop,
example:
while (x.compare("bow") != 0)
{
cout << "sorry, wrong input, try again...";
cin >> x;
}
note the use of the compare method instead of the == operator
here more about it in the documentation
You can use return value of cin >> [your input object] here to check status or istream's method fail(). As soon as input stream fails to parse whole or part of streams it fails and stay in state of failure until you clear it. Unparsed input is preserved (so you can try to parse it differently?)m so if you try to >> again to object of same type, you'll get same failure. To ignore N chars of imput, there is method
istream::ignore(streamsize amount, int delim = EOF)
Example:
int getInt()
{
while (1) // Loop until user enters a valid input
{
std::cout << "Enter an int value: ";
long long x; // if we'll use char, cin would assume it is character
// other integral types are fine
std::cin >> x;
// if (! (std::cin >> x))
if (std::cin.fail()) // has a previous extraction failed?
{
// yep, so let's handle the failure, or next >> will try parse same input
std::cout << "Invalid input from user.\n";
std::cin.clear(); // put us back in 'normal' operation mode
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n'); // and remove the bad input
}
// Thechnically you may do only the above part, but then you can't distingusih invalid format from out of range
else if(( x > std::numeric_limits<int>::max()) ||
( x < std::numeric_limits<int>::min()))
{
std::cout << "Invalid value.\n";
}
else // nope, so return our good x
return x;
}
}
For strings parsing is almost always successful but you'll need some mechanism of comparison of string you have and one that is allowed. Try look for use of std::find() and some container that would contain allowed options, e.g. in form of pair<int,string>, and use int index in switch() statement (or use find_if and switch() within the function you give to it).
Consider that if() statement is a one_direction road, it checks the condition and if the condition was satisfied it goes to its bracket and do blah blah blah , if there is any problem with condition compiler passes ifand jump to compile other codes.
Every time that you begin to compile the codes it begins from int main() function. You did the wrong thing in the if and else statements again
Here is the correct code .I did the necessary changes.
#include "stdafx.h"
#include <iostream>
#include <string>
using std::string;
using std::cin;
using std::cout;
#define coins 500 ;
#define bow_cost 200 ;
int shop(string x)
{
//There is no need to allocate extra memory for 500 and 200 while they are constant.``
cout << "welcome to the shop\n";
cout << "Bow(bow)costs 150 coins.\n";
do
{
cout << "Input another :\n";
cin >> x;
if (x == "bow")
{
return (coins - bow_cost); //return to function as integer
}
} while (true);
}
int main()
{
string name, i;
cout << "if you wish to visit the shop type \"shop\"\n";
cin >> i;
if (i == "shop")
{
cout << "Input :\n";
cin >> name;
cout << shop(name) << "you bought the bow.\n you now have " << " coins." << "\n";
}
//argument passed to shop funnction parameters.
system("pause");
return 0;
}
I have a problem with this code:
int main()
{
int x, sum = 0, how_many;
vector<int> v;
cout << "Write few numbers (write a letter if u want to end)\n";
while (cin >> x)
{
v.push_back(x);
}
cout << "How many of those first numbers do u want to sum up?" << endl;
cin >> how_many;
for (int i = 0; i < how_many; ++i)
{
sum += v[i];
}
cout << "The sum of them is " << sum;
return 0;
}
The problem is that console doesn't let me even write sth into how_many and error occurs. When I put lines 6 and 7 before cout << "Write few..." it all works perfectly. Can someone tell me why is that happening?
The loop ends when cin fails to convert the input into an integer, which leaves cin in a bad state. It also still contains final line of input. Any further input will fail, unless you clear the bad state:
cin.clear(); // clear the error state
cin.ignore(-1); // ignore any input still in the stream
(If you like verbosity, you could specify std::numeric_limits<std::stream_size>::max(), rather than relying on the conversion of -1 to the maximum value of an unsigned type).
You need to clear the cin error state because you ended the int vector read operation by an error.
cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
I have the following simple code:
#include <iostream>
int main()
{
int a;
std::cout << "enter integer a" << std::endl;
std::cin >> a ;
if (std::cin.fail())
{
std::cin.clear();
std::cout << "input is not integer, re-enter please" <<std::endl;
std::cin >>a;
std::cout << "a inside if is: " << a <<std::endl;
}
std::cout << "a is " << a <<std::endl;
std::cin.get();
return 0;
}
When I run the above code and input: 1.5, it outputs: a is 1. FYI: I compile and run the code with gcc 4.5.3.
This means that if cin expects an integer but sees a float, it will do the conversion implicitly. So does this mean that when cin sees a float number, it is not in fail() state? Why this is the case? Is it because C++ does implicit conversion on >> operator?
I also tried the following code to decide whether a given input number is integer following idea from this post: testing if given number is integer:
#include <iostream>
bool integer(float k)
{
if( k == (int) k) return true;
return false;
}
int main()
{
int a;
std::cout << "enter integer a"<< std::endl;
std::cin >> a ;
if (!integer(a))
{
std::cout << "input is not integer, re-enter please" ;
std::cin.clear();
std::cin >> a;
std::cout << "a inside if is: " << a <<std::endl;
}
std::cout << "a is " << a <<std::endl;
std::cin.get();
return 0;
}
This block of code was also not able to test whether a is integer since it simply skip the if block when I run it with float input.
So why this is the case when getting user input with cin? What if sometimes I want the input to be 189, but typed 18.9 by accident, it will result in 18 in this case, which is bad. So does this mean using cin to get user input integers is not a good idea?
thank you.
When you read an integer and you give it an input of 1.5, what it sees is the integer 1, and it stops at the period since that isn't part of the integer. The ".5" is still in the input. This is the reason that you only get the integer part and it is also the reason why it doesn't seem to wait for input the second time.
To get around this, you could read a float instead of an integer so it reads the whole value, or you could check to see if there is anything else remaining on the line after reading the integer.
When reading user input I prefer not to use operator>> as user input is usally line based and prone to errors. I find it best to read a line at a time and validate:
std::string line;
std::getline(std::cin, line);
This also makes it easy to check for different types of numbers.
std::stirngstream linestream(line);
int val;
char c;
if ((linestream >> val) && !(linestream >> c))
{
// Get in here if an integer was read.
// And there is no following (non white space) characters.
// i.e. If the user only types in an integer.
//
// If the user typed any other character after the integer (like .5)
// then this will fail.
}
Of course boost already supports this:
val = boost::lexical_cast<int>(linestream); // Will throw if linestream does
// not contain an integer or
// contains anything in addition
// to the integer.
Boost of course will convert floats as well.
I have some snippet which is kind a poor coding, but it works.
This method is pretty simple, but doesn't handle case when input value is invalid.
See more: https://en.cppreference.com/w/cpp/string/byte/atof
static float InputFloat(std::string label)
{
std::string input;
std::cout << label;
std::cin >> input;
return atof(input.c_str());
}
int main()
{
float value = InputFloat("Enter some float value: ");
std::cout << "value = " << value;
return 0;
}