I am new to C++ and something wrong is happening,
Basically, I have declared a variable called number which is of type int.
If I input a string such as a or x... then number becomes 0. I don't want number to become 0 and instead want it to be error handled.
How do I prevent this is C++? This is my source code...
#include <iostream>
using namespace std;
int number;
int main() {
cout << "Please input a number: ";
cin >> number;
cout << number << endl;
return 0;
}
You need to check what happened in cin:
if (cin >> number) {
cout << number << endl;
}
else {
cout << "error: I wanted a number." << endl;
}
For this you can store the value in a temporary string and then do some conversions to int and double:
#include <iostream>
#include <string>
#include <stdlib.h> //needed for strtod
using namespace std;
int main() {
string str;
cin >> str; //Store input in string
char* ptr; //This will be set to the next character in str after numerical value
double number = strtod(str.c_str(), &ptr); //Call the c function to convert the string to a double
if (*ptr != '\0') { //If the next character after number isn't equal to the end of the string it is not a valid number
//is not a valid number
cout << "It is not a valid number" << endl;
} else {
int integer = atoi(str.c_str());
if (number == (double)integer) { //if the conversion to double is the same as the conversion to int, there is not decimal part
cout << number << endl;
} else {
//Is a floating point
cout << "It is a double or floating point value" << endl;
}
}
return 0;
}
Please note that global variables are bad, write them inside a scope (a function or a class, for example)
Related
Here, When I input CO2, it is processing the 'else' statement and if I input anything else it is still the same
I tried changing 'co2' to "co2" but then it doesn't even work
int main(int nNumberofArgs, char* pszArgs)
{
char symb[5];
cout << "Enter Symbol: ";
cin >> symb[5];
if (symb[5] == 'co2')
{
cout << "This is Carbon-Dioxide" << endl;
}
else
{
cout << "Error" << endl;
}
return 0;
}
Your code is written all wrong.
The statement char symb[5]; declares a fixed sized array that can hold 5 char elements max. But when you do cin >> symb[5];, you are not reading up to 5 chars into the array, you are reading a single char into the 6th slot of the array, corrupting surrounding memory.
Also, symb[5] == 'co2' is not the right way to compare the contents of the array. You are comparing the 6th (invalid) char against a single multi-byte character, you are not comparing the whole content of the array against a multi-character string.
Try something more like this instead:
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char symb[5];
cout << "Enter Symbol: ";
cin.get(symb, 5);
if (strcmp(symb, "co2") == 0)
{
cout << "This is Carbon-Dioxide" << endl;
}
else
{
cout << "Error" << endl;
}
return 0;
}
That being said, using a std::string instead of a char[] is better:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string symb;
cout << "Enter Symbol: ";
cin >> symb;
if (symb == "co2")
{
cout << "This is Carbon-Dioxide" << endl;
}
else
{
cout << "Error" << endl;
}
return 0;
}
I'm trying to make a loop to check input strings for numbers only, and negative numbers are allowed. I'm new to programming, this is for a class project.
This code works, to an extent. When it shows the output, it does not show the first number, and does not allow - to be used. I cannot figure out where I'm going wrong in this.
#include "stdafx.h"
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
string userInput;
int i = 0;
bool checkInput(int);
int main()
{
do
{
cout << "Please enter a numeric value : ";
string userInput;
cin >> userInput[i];
}
while (!checkInput(userInput[i]));
system("pause");
return 0;
}
bool checkInput(int input)
{
string userInput;
int i;
cin >> userInput;
for (int i = 0; i < userInput.length(); i++)
if (isdigit(userInput[i]))
{
cout << "\nYour input " << userInput << " is a valid numeric input." << endl;
return true;
}
else
{
cout << "Please enter a valid numeric value: ";
cin >> userInput[i];
return false;
}
}
Your code doesn't work because you are not utilizing std::string correctly.
When main() prompts the user, it reads into a char of an empty std::string, which is undefined behavior. You should be reading into the std::string itself without calling its operator[] at all. operator>> has an overload for reading std::string values.
checkInput() is just all kinds of wrong. It takes an int as input instead of a std::string, but ignores that input and waits for the user to type in another string value. Then it loops through that string instead of the one read by main(), and only checks the 1st char before exiting. If the char is a digit, checkInput() returns true, and main() exits. Otherwise, checkInput() prompts the user to type in yet another char and then returns false, which then causes main() to prompt the user to type in yet another char. checkInput() does not actually loop through an entire string at all, and does no have any handling for the - character.
Try this instead:
#include "stdafx.h"
#include <iostream>
#include <string>
#include <cctype>
#include <limits>
using namespace std;
bool checkInput(const string &);
int main()
{
string userInput;
cout << "Please enter a numeric value : ";
do
{
cin >> userInput;
if (checkInput(userInput))
break;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Please enter a valid numeric value: ";
}
while (true);
cout << "\nYour input " << userInput << " is a valid numeric input." << endl;
system("pause");
return 0;
}
bool checkInput(const string &input)
{
if (input.empty())
return false;
string::size_type i = 0;
if (input[0] == '-')
{
++i;
if (i == input.length())
return false;
}
do
{
if (!isdigit(input[i]))
return false;
}
while (++i < input.length());
return true;
}
However, the best way to handle this situation is to simply not allow the user to enter non-integer values to begin with. operator>> has overloads for reading integer values, both signed and unsigned types. In this case, reading int values will suffice. Let cin do all of the input validation for you:
#include "stdafx.h"
#include <iostream>
#include <limits>
using namespace std;
int main()
{
int userInput;
cout << "Please enter a numeric value : ";
while (!(cin >> userInput))
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Please enter a valid numeric value: ";
}
cout << "\nYour input " << userInput << " is a valid numeric input." << endl;
system("pause");
return 0;
}
I was typing this and it asks the user to input two integers which will then become variables. From there it will carry out simple operations.
How do I get the computer to check if what is entered is an integer or not? And if not, ask the user to type an integer in. For example: if someone inputs "a" instead of 2, then it will tell them to reenter a number.
Thanks
#include <iostream>
using namespace std;
int main ()
{
int firstvariable;
int secondvariable;
float float1;
float float2;
cout << "Please enter two integers and then press Enter:" << endl;
cin >> firstvariable;
cin >> secondvariable;
cout << "Time for some simple mathematical operations:\n" << endl;
cout << "The sum:\n " << firstvariable << "+" << secondvariable
<<"="<< firstvariable + secondvariable << "\n " << endl;
}
You can check like this:
int x;
cin >> x;
if (cin.fail()) {
//Not an int.
}
Furthermore, you can continue to get input until you get an int via:
#include <iostream>
int main() {
int x;
std::cin >> x;
while(std::cin.fail()) {
std::cout << "Error" << std::endl;
std::cin.clear();
std::cin.ignore(256,'\n');
std::cin >> x;
}
std::cout << x << std::endl;
return 0;
}
EDIT: To address the comment below regarding input like 10abc, one could modify the loop to accept a string as an input. Then check the string for any character not a number and handle that situation accordingly. One needs not clear/ignore the input stream in that situation. Verifying the string is just numbers, convert the string back to an integer. I mean, this was just off the cuff. There might be a better way. This won't work if you're accepting floats/doubles (would have to add '.' in the search string).
#include <iostream>
#include <string>
int main() {
std::string theInput;
int inputAsInt;
std::getline(std::cin, theInput);
while(std::cin.fail() || std::cin.eof() || theInput.find_first_not_of("0123456789") != std::string::npos) {
std::cout << "Error" << std::endl;
if( theInput.find_first_not_of("0123456789") == std::string::npos) {
std::cin.clear();
std::cin.ignore(256,'\n');
}
std::getline(std::cin, theInput);
}
std::string::size_type st;
inputAsInt = std::stoi(theInput,&st);
std::cout << inputAsInt << std::endl;
return 0;
}
Heh, this is an old question that could use a better answer.
User input should be obtained as a string and then attempt-converted to the data type you desire. Conveniently, this also allows you to answer questions like “what type of data is my input?”
Here is a function I use a lot. Other options exist, such as in Boost, but the basic premise is the same: attempt to perform the string→type conversion and observe the success or failure:
template <typename T>
auto string_to( const std::string & s )
{
T value;
std::istringstream ss( s );
return ((ss >> value) and (ss >> std::ws).eof()) // attempt the conversion
? value // success
: std::optional<T> { }; // failure
}
Using the optional type is just one way. You could also throw an exception or return a default value on failure. Whatever works for your situation.
Here is an example of using it:
int n;
std::cout << "n? ";
{
std::string s;
getline( std::cin, s );
auto x = string_to <int> ( s );
if (!x) return complain();
n = *x;
}
std::cout << "Multiply that by seven to get " << (7 * n) << ".\n";
limitations and type identification
In order for this to work, of course, there must exist a method to unambiguously extract your data type from a stream. This is the natural order of things in C++ — that is, business as usual. So no surprises here.
The next caveat is that some types subsume others. For example, if you are trying to distinguish between int and double, check for int first, since anything that converts to an int is also a double.
There is a function in c called isdigit(). That will suit you just fine. Example:
int var1 = 'h';
int var2 = '2';
if( isdigit(var1) )
{
printf("var1 = |%c| is a digit\n", var1 );
}
else
{
printf("var1 = |%c| is not a digit\n", var1 );
}
if( isdigit(var2) )
{
printf("var2 = |%c| is a digit\n", var2 );
}
else
{
printf("var2 = |%c| is not a digit\n", var2 );
}
From here
If istream fails to insert, it will set the fail bit.
int i = 0;
std::cin >> i; // type a and press enter
if (std::cin.fail())
{
std::cout << "I failed, try again ..." << std::endl
std::cin.clear(); // reset the failed state
}
You can set this up in a do-while loop to get the correct type (int in this case) propertly inserted.
For more information: http://augustcouncil.com/~tgibson/tutorial/iotips.html#directly
You can use the variables name itself to check if a value is an integer.
for example:
#include <iostream>
using namespace std;
int main (){
int firstvariable;
int secondvariable;
float float1;
float float2;
cout << "Please enter two integers and then press Enter:" << endl;
cin >> firstvariable;
cin >> secondvariable;
if(firstvariable && secondvariable){
cout << "Time for some simple mathematical operations:\n" << endl;
cout << "The sum:\n " << firstvariable << "+" << secondvariable
<<"="<< firstvariable + secondvariable << "\n " << endl;
}else{
cout << "\n[ERROR\tINVALID INPUT]\n";
return 1;
}
return 0;
}
I prefer to use <limits> to check for an int until it is passed.
#include <iostream>
#include <limits> //std::numeric_limits
using std::cout, std::endl, std::cin;
int main() {
int num;
while(!(cin >> num)){ //check the Input format for integer the right way
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cout << "Invalid input. Reenter the number: ";
};
cout << "output= " << num << endl;
return 0;
}
Under C++11 and later, I have the found the std::stoi function very useful for this task. stoi throws an invalid_argument exception if conversion cannot be performed. This can be caught and handled as shown in the demo function 'getIntegerValue' below.
The stoi function has a second parameter 'idx' that indicates the position of the first character in the string after the number. We can use the value in idx to check against the string length and ascertain if there are any characters in the input other than the number. This helps eliminate input like 10abc or a decimal value.
The only case where this approach fails is when there is trailing white space after the number in the input, that is, the user enters a lot of spaces after inputting the number. To handle such a case, you could rtrim the input string as described in this post.
#include <iostream>
#include <string>
bool getIntegerValue(int &value);
int main(){
int value{};
bool valid{};
while(!valid){
std::cout << "Enter integer value: ";
valid = getIntegerValue(value);
if (!valid)
std::cout << "Invalid integer value! Please try again.\n" << std::endl;
}
std::cout << "You entered: " << value << std::endl;
return 0;
}
// Returns true if integer is read from standard input
bool getIntegerValue(int &value){
bool isInputValid{};
int valueFromString{};
size_t index{};
std::string userInput;
std::getline(std::cin, userInput);
try {
//stoi throws an invalid_argument exception if userInput cannot be
//converted to an integer.
valueFromString = std::stoi(userInput, &index);
//index being different than length of string implies additional
//characters in input that could not be converted to an integer.
//This is to handle inputs like 10str or decimal values like 10.12
if(index == userInput.length()) isInputValid = true;
}
catch (const std::invalid_argument &arg) {
; //you could show an invalid argument message here.
}
if (isInputValid) value = valueFromString;
return isInputValid;
}
You could use :
int a = 12;
if (a>0 || a<0){
cout << "Your text"<<endl;
}
I'm pretty sure it works.
I'm creating a program which converts decimal values into binary values. The issue I'm having is that in my if statement I'm checking whether the user input for my int decimal variable contains digits before it moves on to converting the values but when it is digits it considers them as alpha characters, which then cause the program to infinitely loop.
When I change isdigit(decimal) to !isdigit(decimal) the conversion works but if I put in alpha characters it will then infinitely loop again. Am I doing something really silly?
#include <iostream>
#include <string>
#include <ctype.h>
#include <locale>
using namespace std;
string DecToBin(int decimal)
{
if (decimal == 0) {
return "0";
}
if (decimal == 1) {
return "1";
}
if (decimal % 2 == 0) {
return DecToBin(decimal/2) + "0";
}
else {
return DecToBin(decimal/2) + "1";
}
}
int main()
{
int decimal;
string binary;
cout << "Welcome to the Decimal to Binary converter!\n";
while (true) {
cout << "\n";
cout << "Type a Decimal number you wish to convert:\n";
cout << "\n";
cin >> decimal;
cin.ignore();
if (isdigit(decimal)) { //Is there an error with my code here?
binary = DecToBin(decimal);
cout << binary << "\n";
} else {
cout << "\n";
cout << "Please enter a number.\n";
}
}
cin.get();
}
First of all, to check for a number in a mixture of number and characters, do not take input into an int. Always go with std::string
int is_num(string s)
{
for (int i = 0; i < s.size(); i++)
if (!isdigit(s[i]))
return 0;
return 1;
}
int main()
{
int decimal;
string input;
string binary;
cout << "Welcome to the Decimal to Binary converter!\n";
while (true) {
cout << "\n";
cout << "Type a Decimal number you wish to convert:\n";
cout << "\n";
cin >> input;
cin.ignore();
if (is_num(input)) { //<-- user defined function
decimal = atoi(input.c_str()); //<--used C style here
binary = DecToBin(decimal);
cout << binary << "\n";
} else {
cout << "\n";
cout << "Please enter a number.\n";
}
}
cin.get();
}
You can always write a function to check for number in a string as shown above. Now your code does not run into an infinite loop. Moreover if you want to take only one valid input and exit the program, u can add a break
if (is_num(input)) {
decimal = atoi(input.c_str());
binary = DecToBin(decimal);
cout << binary << "\n";
break; //<--
}
I was typing this and it asks the user to input two integers which will then become variables. From there it will carry out simple operations.
How do I get the computer to check if what is entered is an integer or not? And if not, ask the user to type an integer in. For example: if someone inputs "a" instead of 2, then it will tell them to reenter a number.
Thanks
#include <iostream>
using namespace std;
int main ()
{
int firstvariable;
int secondvariable;
float float1;
float float2;
cout << "Please enter two integers and then press Enter:" << endl;
cin >> firstvariable;
cin >> secondvariable;
cout << "Time for some simple mathematical operations:\n" << endl;
cout << "The sum:\n " << firstvariable << "+" << secondvariable
<<"="<< firstvariable + secondvariable << "\n " << endl;
}
You can check like this:
int x;
cin >> x;
if (cin.fail()) {
//Not an int.
}
Furthermore, you can continue to get input until you get an int via:
#include <iostream>
int main() {
int x;
std::cin >> x;
while(std::cin.fail()) {
std::cout << "Error" << std::endl;
std::cin.clear();
std::cin.ignore(256,'\n');
std::cin >> x;
}
std::cout << x << std::endl;
return 0;
}
EDIT: To address the comment below regarding input like 10abc, one could modify the loop to accept a string as an input. Then check the string for any character not a number and handle that situation accordingly. One needs not clear/ignore the input stream in that situation. Verifying the string is just numbers, convert the string back to an integer. I mean, this was just off the cuff. There might be a better way. This won't work if you're accepting floats/doubles (would have to add '.' in the search string).
#include <iostream>
#include <string>
int main() {
std::string theInput;
int inputAsInt;
std::getline(std::cin, theInput);
while(std::cin.fail() || std::cin.eof() || theInput.find_first_not_of("0123456789") != std::string::npos) {
std::cout << "Error" << std::endl;
if( theInput.find_first_not_of("0123456789") == std::string::npos) {
std::cin.clear();
std::cin.ignore(256,'\n');
}
std::getline(std::cin, theInput);
}
std::string::size_type st;
inputAsInt = std::stoi(theInput,&st);
std::cout << inputAsInt << std::endl;
return 0;
}
Heh, this is an old question that could use a better answer.
User input should be obtained as a string and then attempt-converted to the data type you desire. Conveniently, this also allows you to answer questions like “what type of data is my input?”
Here is a function I use a lot. Other options exist, such as in Boost, but the basic premise is the same: attempt to perform the string→type conversion and observe the success or failure:
template <typename T>
auto string_to( const std::string & s )
{
T value;
std::istringstream ss( s );
return ((ss >> value) and (ss >> std::ws).eof()) // attempt the conversion
? value // success
: std::optional<T> { }; // failure
}
Using the optional type is just one way. You could also throw an exception or return a default value on failure. Whatever works for your situation.
Here is an example of using it:
int n;
std::cout << "n? ";
{
std::string s;
getline( std::cin, s );
auto x = string_to <int> ( s );
if (!x) return complain();
n = *x;
}
std::cout << "Multiply that by seven to get " << (7 * n) << ".\n";
limitations and type identification
In order for this to work, of course, there must exist a method to unambiguously extract your data type from a stream. This is the natural order of things in C++ — that is, business as usual. So no surprises here.
The next caveat is that some types subsume others. For example, if you are trying to distinguish between int and double, check for int first, since anything that converts to an int is also a double.
There is a function in c called isdigit(). That will suit you just fine. Example:
int var1 = 'h';
int var2 = '2';
if( isdigit(var1) )
{
printf("var1 = |%c| is a digit\n", var1 );
}
else
{
printf("var1 = |%c| is not a digit\n", var1 );
}
if( isdigit(var2) )
{
printf("var2 = |%c| is a digit\n", var2 );
}
else
{
printf("var2 = |%c| is not a digit\n", var2 );
}
From here
If istream fails to insert, it will set the fail bit.
int i = 0;
std::cin >> i; // type a and press enter
if (std::cin.fail())
{
std::cout << "I failed, try again ..." << std::endl
std::cin.clear(); // reset the failed state
}
You can set this up in a do-while loop to get the correct type (int in this case) propertly inserted.
For more information: http://augustcouncil.com/~tgibson/tutorial/iotips.html#directly
You can use the variables name itself to check if a value is an integer.
for example:
#include <iostream>
using namespace std;
int main (){
int firstvariable;
int secondvariable;
float float1;
float float2;
cout << "Please enter two integers and then press Enter:" << endl;
cin >> firstvariable;
cin >> secondvariable;
if(firstvariable && secondvariable){
cout << "Time for some simple mathematical operations:\n" << endl;
cout << "The sum:\n " << firstvariable << "+" << secondvariable
<<"="<< firstvariable + secondvariable << "\n " << endl;
}else{
cout << "\n[ERROR\tINVALID INPUT]\n";
return 1;
}
return 0;
}
I prefer to use <limits> to check for an int until it is passed.
#include <iostream>
#include <limits> //std::numeric_limits
using std::cout, std::endl, std::cin;
int main() {
int num;
while(!(cin >> num)){ //check the Input format for integer the right way
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cout << "Invalid input. Reenter the number: ";
};
cout << "output= " << num << endl;
return 0;
}
Under C++11 and later, I have the found the std::stoi function very useful for this task. stoi throws an invalid_argument exception if conversion cannot be performed. This can be caught and handled as shown in the demo function 'getIntegerValue' below.
The stoi function has a second parameter 'idx' that indicates the position of the first character in the string after the number. We can use the value in idx to check against the string length and ascertain if there are any characters in the input other than the number. This helps eliminate input like 10abc or a decimal value.
The only case where this approach fails is when there is trailing white space after the number in the input, that is, the user enters a lot of spaces after inputting the number. To handle such a case, you could rtrim the input string as described in this post.
#include <iostream>
#include <string>
bool getIntegerValue(int &value);
int main(){
int value{};
bool valid{};
while(!valid){
std::cout << "Enter integer value: ";
valid = getIntegerValue(value);
if (!valid)
std::cout << "Invalid integer value! Please try again.\n" << std::endl;
}
std::cout << "You entered: " << value << std::endl;
return 0;
}
// Returns true if integer is read from standard input
bool getIntegerValue(int &value){
bool isInputValid{};
int valueFromString{};
size_t index{};
std::string userInput;
std::getline(std::cin, userInput);
try {
//stoi throws an invalid_argument exception if userInput cannot be
//converted to an integer.
valueFromString = std::stoi(userInput, &index);
//index being different than length of string implies additional
//characters in input that could not be converted to an integer.
//This is to handle inputs like 10str or decimal values like 10.12
if(index == userInput.length()) isInputValid = true;
}
catch (const std::invalid_argument &arg) {
; //you could show an invalid argument message here.
}
if (isInputValid) value = valueFromString;
return isInputValid;
}
You could use :
int a = 12;
if (a>0 || a<0){
cout << "Your text"<<endl;
}
I'm pretty sure it works.