C++ code - Error message when floating point is entered [duplicate] - c++

I've written a program that returns the median value of a user-defined array. While I've put a few checks in my code (array size can not be negative) I keep running into one issue I simply can not fix (for clarity sake, assume strings and alphabetical characters will not be used).
All of my input values are int however the user could just as easily enter in a float. When they do this (either for size of array or entering in the element) it breaks my code. I've tried multiple things to try and catch this, but it seems like the way my program is getting the value doesn't allow for the catch in time.
#include <iostream>
using namespace std;
void sort(int * a,int n)
{
for(int i=0;i<n;++i)
for(int j=i+1;j<n;++j)
{
if(a[i]>a[j])
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}\
}
return;
}
int main()
{
int n;
int check;
int x;
cout<<"Enter length of array:";
cin>>n;
if (n < 0){
while (n < 0){
cout << "Please enter a length greater than 0" << endl;
cin >> n;
}
} else if (n % 1 != 0){
while (n % 1 != 0){
cout << "Whole numbers only! Try again" << endl;
cin >> n;
}
}
if (n == 0){
cout <<"You try to enter numbers, but there's no place to put them." << endl;
cout << ":(";
return 0;
}
int a[n];
cout<<"Enter values one by one:\n";
for(int i=0;i<n;++i){
cin >> x;
a[i] = int(x);
}
sort(a,n);
if (n % 2 == 1){
cout<<"Median is:"<<a[n/2]<<endl;
}
else{
float z = (float(a[n/2]) + float(a[(n/2)-1])) / 2;
cout << "Median is:" << z << endl;
}
return 0;
}
First thing I tried was catching the float like so
`if (n % 1 !=0){
while(n % 1 !=0){
cout << "Enter a whole number"
cin >> n
}
}`
This still broke my program. The odd thing was that I entered a float and then printed the value of n and it only showed the int value.
I tried using typeid.n() with #include <typeinfo>and comparing that to an int type to check it was the correct value, but that slipped through as well.
I tried doing an int cast, something like int(n) immediately after number was stored in n but before it went into a[n] and yet again, it still broke my code.
How can I check against float user-input and loop them until they give me an int?

You're reading into an int:
int x;
...
cin >> x;
So it will read what it can, then stop at e.g. a . and leave the rest on the stream (like if the user enters "123.4" you'll get 123 and then ".4" won't be consumed from the input stream).
Instead, you could read into a float:
float x;
...
cin >> x;
And do the appropriate math.
Alternatively you could read into a string and parse it into a float. That way you won't get stuck at letters and such either.
And the final option is to read into an int but handle any errors and skip the bad input, which is detailed at How to handle wrong data type input so I won't reproduce it here.
Which option you choose really just depends on what you want the behavior of your program to be and how strictly you want to validate input (e.g. round vs. fail if "2.5" is entered but an integer is expected, how do you want to handle "xyz" as input, etc.).

Related

Infinite loop when using exceptions in c++11

I would like to create a c++11 program that takes in 10 positive integers and gives the user the total. In the event of a negative number or a char input, the exception should be thrown and the user must re enter their value.
The program below works with negative numbers. However, when I enter a character like "a", the program goes into an infinite loop and I cannot figure out why.
Any and all help will be appreciated
#include <iostream>
int main(){
int array[10] = {0};
int total = 0;
for(int i =0; i < 10; i++){
std::cout<<"Number "<< i+1 << ": " <<std::endl;
std::cin >> array[i];
try{
if(array[i] < 0 || std::cin.fail())
throw(array[i]);
}
catch(int a){
std::cout<< a <<" is not a positive number! "<<std::endl;
i-=1; // to go back to the previous position in array
}
}
for(int k = 0; k < 10; k++)
total+=array[k];
std::cout<<"Total: " <<total<<std::endl;
}
If you get invalid input there are two things to thing you need to do:
Clear the stream status. This is done using the clear function.
Remove the invalid input from the buffer. This is usually done using the ignore function.
As for your program, you don't need exceptions here, just using unsigned integers and checking the status is enough:
unsigned int array[10] = { 0 };
...
if (!(std::cin >> array[i])
{
std::cout << "Please input only non-negative integers.\n";
// First clear the stream status
std::cin.clear();
// Then skip the bad input
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// Make sure the index isn't increased
--i;
}
To use exceptions similar to what you do now, the solution is almost exactly the same as above:
unsigned int array[10] = { 0 };
...
if (!(std::cin >> array[i])
{
throw i;
}
catch (int current_index)
{
std::cout << "The input for number " << current_index + 1 << " was incorrect.\n";
std::cout << "Please input only non-negative integers.\n";
// First clear the stream status
std::cin.clear();
// Then skip the bad input
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// Make sure the index isn't increased
--i;
}
Do not forget to include limits header file while using following line in your code :
std::cin.ignore(std::numeric_limits::max(), '\n');
because numeric_limits template is defined in this header file !

Floats breaking my code

I've written a program that returns the median value of a user-defined array. While I've put a few checks in my code (array size can not be negative) I keep running into one issue I simply can not fix (for clarity sake, assume strings and alphabetical characters will not be used).
All of my input values are int however the user could just as easily enter in a float. When they do this (either for size of array or entering in the element) it breaks my code. I've tried multiple things to try and catch this, but it seems like the way my program is getting the value doesn't allow for the catch in time.
#include <iostream>
using namespace std;
void sort(int * a,int n)
{
for(int i=0;i<n;++i)
for(int j=i+1;j<n;++j)
{
if(a[i]>a[j])
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}\
}
return;
}
int main()
{
int n;
int check;
int x;
cout<<"Enter length of array:";
cin>>n;
if (n < 0){
while (n < 0){
cout << "Please enter a length greater than 0" << endl;
cin >> n;
}
} else if (n % 1 != 0){
while (n % 1 != 0){
cout << "Whole numbers only! Try again" << endl;
cin >> n;
}
}
if (n == 0){
cout <<"You try to enter numbers, but there's no place to put them." << endl;
cout << ":(";
return 0;
}
int a[n];
cout<<"Enter values one by one:\n";
for(int i=0;i<n;++i){
cin >> x;
a[i] = int(x);
}
sort(a,n);
if (n % 2 == 1){
cout<<"Median is:"<<a[n/2]<<endl;
}
else{
float z = (float(a[n/2]) + float(a[(n/2)-1])) / 2;
cout << "Median is:" << z << endl;
}
return 0;
}
First thing I tried was catching the float like so
`if (n % 1 !=0){
while(n % 1 !=0){
cout << "Enter a whole number"
cin >> n
}
}`
This still broke my program. The odd thing was that I entered a float and then printed the value of n and it only showed the int value.
I tried using typeid.n() with #include <typeinfo>and comparing that to an int type to check it was the correct value, but that slipped through as well.
I tried doing an int cast, something like int(n) immediately after number was stored in n but before it went into a[n] and yet again, it still broke my code.
How can I check against float user-input and loop them until they give me an int?
You're reading into an int:
int x;
...
cin >> x;
So it will read what it can, then stop at e.g. a . and leave the rest on the stream (like if the user enters "123.4" you'll get 123 and then ".4" won't be consumed from the input stream).
Instead, you could read into a float:
float x;
...
cin >> x;
And do the appropriate math.
Alternatively you could read into a string and parse it into a float. That way you won't get stuck at letters and such either.
And the final option is to read into an int but handle any errors and skip the bad input, which is detailed at How to handle wrong data type input so I won't reproduce it here.
Which option you choose really just depends on what you want the behavior of your program to be and how strictly you want to validate input (e.g. round vs. fail if "2.5" is entered but an integer is expected, how do you want to handle "xyz" as input, etc.).

How to take numerous inputs without assigning variable to each of them in C++?

I'm beginning with C++. The question is: to write a program to input 20 natural numbers and output the total number of odd numbers inputted using while loop.
Although the logic behind this is quite simple, i.e. to check whether the number is divisible by 2 or not. If no, then it is an odd number.
But, what bothers me is, do I have to specifically assign 20 variables for the user to input 20 numbers?
So, instead of writing cin>>a>>b>>c>>d>>.. 20 variables, can something be done to reduce all this calling of 20 variables, and in cases like accepting 50 numbers?
Q. Count total no of odd integer.
A.
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
int n,odd=0;
cout<<"Number of input's\n";
cin>>n;
while(n-->0)
{
int y;
cin>>y;
if(y &1)
{
odd+=1;
}
}
cout<<"Odd numbers are "<<odd;
return 0;
}
You can process the input number one by one.
int i = 0; // variable for loop control
int num_of_odds = 0; // variable for output
while (i < 20) {
int a;
cin >> a;
if (a % 2 == 1) num_of_odds++;
i++;
}
cout << "there are " << num_of_odds << " odd number(s)." << endl;
If you do really want to save all the input numbers, you can use an array.
int i = 0; // variable for loop control
int a[20]; // array to store all the numbers
int num_of_odds = 0; // variable for output
while (i < 20) {
cin >> a[i];
i++;
}
i = 0;
while (i < 20) {
if (a[i] % 2 == 1) num_of_odds++;
i++;
}
cout << "there are " << num_of_odds << " odd number(s)." << endl;
Actually, you can also combine the two while-loop just like the first example.
Take one input and then process it and then after take another intput and so on.
int n= 20; // number of input
int oddnum= 0; //number of odd number
int input;
for (int i = 0; i < n; i ++){
cin >> input;
if (input % 2 == 1) oddnum++;
}
cout << "Number of odd numbers :"<<oddnum << "\n";

C++ Excluding non-integer user inputs

I am making a number-guessing game where the user is asked to input a four-digit number. It is possible, however, that the user inputs less or more than four digits and/or a non-integer input (i.e. invalid input). My code stores the user input into an integer-type array. I just realized now that my code will still recognize "invalid inputs" as valid since the array where the input is being stored is declared as an integer-type. Below is a portion of my code:
#include <iostream>
using namespace std;
void guess(int num_guess[], int size);
int main(){
int list[4];
guess(list, 4);
for(int i = 0; i < 4; i++){
cout << list[i];
}
cout << endl;
}
void guess(int num_guess[], int size){
int number;
cin >> number;
for(int i = size-1; i >= 0; i--){
num_guess[i] = number%10;
number /= 10;
}
}
cout << list[i]; isn't really part of the original code, but this was how I found out that invalid inputs are still accepted. I encountered a similar problem before when I was making a rational roots calculator program in Python, but it was much easier then to detect and exclude unwanted inputs. My question is, how do I fix my code so that it can detect invalid inputs and output something like "Invalid input" and then proceed to ask the user for another input.
The following is a function to check if a string is a 4 digit positive integer. If the number could be negative, you just need to check if the s[0] == '-'.
bool check(string &s){
if(s.size() != 4) return false;
for(int i=0; i < 4; i++){
if(s[i] < '0' || s[i] > '9') return false;
}
return true;
}
The following is a function to convert a string to an int:
#include <stringstream>
int strToInt(string &s){
stringstream ss(s);
int ans;
ss >> ans;
return ans;
}
To exclude non integer inputs try the following:
void skip_to_int(){
// if is not an integer
if(cin.fail()){
// check character type
cin.clear();
char ch;
while(cin>>ch){
// throw away non digits
if(isdigit(ch)){
// put back if digit to be written
cin.unget();
return;}
}
}
else error ("no input");
}
And your input prompt function will look like this:
cout << "Please enter an integer" << endl;
int n=0;
if(cin>>n){
// integer OK, proceed
}
else{
cout << "That was not a numeric value, try again." << endl;
skip_to_int();}
Here's my solution. Beware, it uses C++11. Certainly not necessary if you use std::stringstream, but this should work pretty well.
I presume you don't want negative numbers. I also presume that any number of 0's in front doesn't make the number a 4-digit number. It will cut off padded 0's, so 01234 is a 4 digit number, but 0123 isn't.
void guess(int num_guess[], int size)
{
int number;
// if the length of the number isn't 4, try again until it is
do {
std::cin >> number;
if(std::to_string(number).length() != size)
std::cout << "You messed up the input. How hard could it be? Try again..." << std::endl;
} while(std::to_string(number).length() != size);
// by now, the size is definitely 4. insert it by digit into num_guess
for(int i = size-1; i >= 0; i++) {
num_guess[i] = number%10;
number /= 10;
}
}
#include <iostream>
#include <limits>
int main() {
int i = 0;
std::cout << "Please enter a number with four digits: ";
while( !(std::cin >> i) || !(i / 1000.0f >= 1.0f) )
{
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "Invalid entry." << std::endl;
std::cout << "Please enter a number with four digits: ";
}
}
the std::cin.clear() clears all errors flags on current stream structure and std::cin.ignore() cleans up the input stream itself. Once we don't know the size of stream 'til this operation I have used the maximum possible value of a stream size to make sure any stream length could be cleaned.
add #include "math.h"
and change guess
void guess(int num_guess[], int size){
int number = 0;
bool firstTime = true;
do
{
if (!firstTime)
cout << " Error, try again " << endl;
firstTime = false;
cin >> number;
} while (number<pow(10, size-1) || number>=pow(10, size));
for(int i = size-1; i >= 0; i--){
num_guess[i] = number%10;
number /= 10;
}
}

cin infinite loop when reading in a non-numeric value

I had a strange behavior in a program and I spent long time trying to deduce why. it was an infinite loop with no sense. Testing these lines of code(under suspicion) i got the same result. Every time I type in a non-numeric value such a symbol, the program runs through an infinite loop printing zeros, which i guess is how cout represents the wrong value entered. I'd like to know why is that weird behavior from cin, printing all those zeros instead of stopping when it finds a wrong reading.
#include <iostream>
using namespace std;
int main()
{
int n = 0;
while(n >= 0) {
cin >> n;
cout << n << endl;
}
return 0;
}
the program runs through an infinite loop printing zeros, which i guess is how cout represents the wrong value entered.
That is not quite right: when you ask cin for an int, but there's no int, you get no value back, but the invalid input remains in the buffer. When you ask for int again in the next iteration of the loop, same thing happens again, and no progress is made: bad data remains in the buffer.
That's why you get an infinite loop. To fix this, you need to add some code to remove bad data from the input buffer. For example, you could read it into a string, and ignore the input:
int n = 0;
while(n <= 0) {
cin >> n;
if (!cin.good()) {
cin.clear();
string ignore;
cin >> ignore;
continue;
}
cout << n << endl;
}
Demo.
You need to "eat" the non-numerical input i.e.
#include <iostream>
using namespace std;
int main()
{
int n = 0;
while(n >= 0) {
cin >> n;
if (!cin) {
char c;
cin >> c;
} else {
cout << n << endl;
}
}
return 0;
}