Determining input to be int or char in C++ - c++

I'm working on a small program for school to compute a factorial of an inputted number. I've got a good amount of experience in Java, but this is my first go at C++.
My problem: I need to be able to have a single input from the user, which is either an integer or the character 'q', which signifies the application needs to quit.
Here is my current attempt:
#include <stdio.h>
#include <iostream>
#include "Header.h"
using namespace std;
int x=0;
char y;
int main(int argc, char *argv[])
{
printf("Hello, please enter a number to compute a factorial (or 'q' to quit): ");
cin >> y;
x= (y-'0');
if(y=='q')
{ printf("Thanks for playing!\n");
exit(1);
}
long result= print_Factorial(x);
cout << x << "!= " << result << "\n";
return result;
}
This casting does not work, however. If I enter a double digit number, such as 12, it only converts to x the first digit of the two and computes that factorial. I'm sure this is simple, what am I missing?
Explicit answer or a lead to where I can learn more about this problem, anything is appreciated.

There are functions you can use to try and covert a string into a number, and which you can check if the conversion was a success or not. The std::strtol function is one of them:
std::string input;
std::cin >> input;
char* endptr = nullptr;
const char *input_ptr = input.c_str();
long value = std::strtol(input_ptr, &endptr, 10);
if (endptr == input_ptr)
{
// Input was not a valid number
}
else if (*endptr != '\0')
{
// Input starts with a valid number, but ends with some extra characters
// (for example "123abc")
// `value` is set to the numeric part of the string
}
else
{
// Input was a valid number
}
If you don't mind exceptions, then you can use e.g. std::stoi instead:
std::string input;
std::cin >> input;
int value = 0;
try
{
size_t endpos = 0;
value = std::stoi(input, &endpos);
if (endpos != input.length())
{
// Input starts with a valid number, but ends with some extra characters
// (for example "123abc")
// `value` is set to the numeric part of the string
}
else
{
// Input is a valid number
}
}
catch (std::invalid_argument&)
{
// Input not a valid number
}
catch (std::out_of_range&)
{
// Input is a valid number, but to big to fit in an `int`
}

The reason you're getting the first digit is because you're using
cin >> y; where y is a char, which holds one character. So you're only getting one character.
What you probably would want to do is get the answer as a string, and once you check that the string is not == "q", then you could convert it to an int.

#include <iostream>
#include <sstream>
int main() {
std::string in;
std::cout << "Please enter a digit: ";
while(std::cin >> in) {
std::cout << "Input: " << in << std::endl;
if(in.size() == 1) {
if(in[0] == 'q' || in[0] == 'Q') {
std::cout << "Quit" << std::endl;
return 0;
}
}
std::istringstream parse(in);
int value;
if(parse >> value) {
if(parse.eof()) {
std::cout << "Success" << std::endl;
return 0;
}
}
std::cout << "Please try again: ";
}
std::cerr << "This should not happen <control + d>" << std::endl;
return 1;
}

Your user can enter whatever line of text, you you have to read a "line of text" to validate.
#include <iostream>
#include <string>
#include <stdexcept>
int main()
{
std::string text;
std::getline(std::cin,text);
if(text.size()==1 && text[0]=='q')
{
std::cout << "quit command";
return 0;
}
try
{
int i = std::stoi(text); //may throw if text is not convertible
/* whatever elaboration and output */
return 0;
}
catch(const std::exception& e)
{
std::cout << "bad input: " << text << '\n';
std::cout << "caused excpetion: " << e.what() << std::endl;
}
return 3; //means "excpetion thorown"
}

Related

I want to take a number from the user and if he type a character or anything else i want him to enter the number again

int x;
if(cin >> x)
cout << "True" << endl;
else
{
cin >> x;
}
It supposes to let me enter the number again but it's end the program without taking the number again
A simple solution is to get the input as string, use regex to check if it's a number and if it is convert it to an int, otherwise ask for input again. Here's an example:
#include <iostream>
#include <string>
#include <regex>
int main() {
std::regex rx(R"((?:^|\s)([+-]?[[:digit:]]+(?:\.[[:digit:]]+)?)(?=$|\s))");
std::string line;
int n;
while ( std::getline(std::cin, line) ) {
if ( std::regex_match(line, rx) ) {
// Input is number
n = std::stoi( line );
std::cout << n << "\n";
break;
}
}
return 0;
}

How to allow only positive integer input from user?

I have been trying to only allow positive integer input into my program. But works it is getting past with the character input and negative integers, decimal numbers. Any ideas how to fix that?
#include <iostream>
using namespace std;
int main()
{
int row, col, i, i1, j, test;
double n;
test = 0;
while (test == 0)
{
cout << "Enter the number of rows: " << endl;
cin >> row;
if (cin.fail() || row <= 0 || !(row == (int)row))
{
cout << "\nEntered value is wrong!";
printf("\n");
cin.clear();
cin.ignore();
test = 0;
}
else { test = 1; }
}
}
I have been trying to only allow positive integer input into my
program.
You can easily check it with the help of std::isdigit, if you take the user input as a string instead of an integer.
take the user input as a string.
for each character in the string, check whether it is a digit (using std::isdigit).
if any of the char's in the user input(which is a string) is not a valid digit, return the boolean = false.
if its true for all chars, the input is an integer and you can convert it back to integer using std::to_string.
Following is a sample code:
SEE LIVE
#include <iostream>
#include <cctype> // std::isdigit
#include <string>
#include <vector>
bool isInteger(const std::string& input)
{
for (const char eachChar : input)
if (!std::isdigit(eachChar))
return false; // if not a digit, return False
return true;
}
int main()
{
std::vector<std::string> inputs{ "123", "-54", "8.5", "45w" }; // some inputs as strings
for(const std::string& input: inputs)
{
if (isInteger(input))
{
// apply std::stoi(input) to convert string input to integer
std::cout << "Input is a valid integer: " << input << std::endl;
}
else { std::cout << input << " is not a valid integer!\n"; }
}
}
output:
Input is a valid integer: 123
-54 is not a valid integer!
8.5 is not a valid integer!
45w is not a valid integer!
This is what you probably want (demo):
#include <iostream>
#include <limits>
int main()
{
using namespace std;
int n;
while ( !( cin >> n ) || n < 0 )
{
cin.clear();
cin.ignore( numeric_limits<std::streamsize>::max(), '\n' );
}
//...
return 0;
}

How to make user input numbers only in C++?

So far, this is my code:
while(bet > remaining_money || bet < 100)
{
cout << "You may not bet lower than 100 or more than your current money. Characters are not accepted." << endl;
cout << "Please bet again: ";
cin >> bet;
}
It works fine but I'm trying to figure out how to make it loop if the user inputs anything that isn't a number as well.
When I press a letter or say a symbol/sign, the code just breaks.
Using the function
isdigit()
This function returns true if the argument is a decimal digit (0–9)
Don't forget to
#include <cctype>
I would use std::getline and std::string to read the whole line and then only break out of the loop when you can convert the entire line to a double.
#include <string>
#include <sstream>
int main()
{
std::string line;
double d;
while (std::getline(std::cin, line))
{
std::stringstream ss(line);
if (ss >> d)
{
if (ss.eof())
{ // Success
break;
}
}
std::cout << "Error!" << std::endl;
}
std::cout << "Finally: " << d << std::endl;
}
A good way of doing this is to take the input as a string. Now find the length of the string as:
int length = str.length();
Make sure to include string and cctype. Now, run a loop that checks the whole string and sees if there is a character that is not a digit.
bool isInt = true;
for (int i = 0; i < length; i++) {
if(!isdigit(str[i]))
isInt = false;
}
If any character is not a digit, isInt will be false. Now, if your input(a string) is all digits, convert it back to an integer as:
int integerForm = stoi(str);
Store integerForm in your array.

Restrict spaces from input in console

I have 3 cin for ints.
int input1;
cin >> input;
int input2;
cin >> input2;
int input3
cin >> input3;
The problem is if i type 2 3 4 in console, it will input all 3 in one shot. How can i prevent this? And possibly give them a warning if they do this. basically error input validating.
One possible solution:
int strict_stoi(const string& s)
{
size_t end_pos;
int num = stoi(s, &end_pos);
for (size_t i=end_pos; i<s.length(); ++i)
{
if (!isspace(s[i]))
throw invalid_argument("You have entered some garbage after the number!");
}
return num;
}
int read_number()
{
string s;
getline(cin, s);
return strict_stoi(s);
}
int read_number_with_retry(const char* prompt)
{
for (;;)
{
try
{
cout << prompt;
return read_number();
}
catch (invalid_argument& ex)
{
cout << ex.what() << endl;
}
}
}
int test()
{
int input1 = read_number_with_retry("Enter input #1: ");
int input2 = read_number_with_retry("Enter input #2: ");
int input3 = read_number_with_retry("Enter input #3: ");
return 0;
}
If you enter a totally invalid argument (for example "a") then it will show you a not too user friendly "invalid stoi argument" message but if you enter "5 6" then it shows "You have entered some garbage after the number!". If you want to replace the "invalid stoi argument" message with something user friendly then instead of throwing an invalid_argument exception when you find "garbage after the number" you should throw you own garbage_after_the_number exception and in this case you could make the distinction between two different errors: invalid_argument would be thrown only in case of invalid inputs (like "a") and garbage_after_the_number would be thrown only in case of the other kind of error so you would be able to catch two different exceptions and you could print totally customized message in these two cases. I leave the implementation of this to you as an extra exercise.
You may do:
#include <iostream>
#include <sstream>
int main() {
while(true) {
std::cout << "Enter a number [Enter to quit]: ";
std::string line;
getline(std::cin, line);
if(line.empty()) break;
else {
std::stringstream input(line);
int number;
// Preceding white space number trailing white space:
input >> number >> std::ws;
if(input && input.eof()) {
std::cout
<< "The number surronded by possible white space is: "
<< number
<< '\n';
}
else {
std::cout
<< "The input line is invalid: "
<< line
<< '\n';
}
}
}
}
And if you want to be strict:
#include <iostream>
#include <iomanip>
#include <sstream>
...
// Number without preceding and trailing white space:
input >> std::noskipws >> number;
...

How to check if the input is a valid integer without any other chars?

#include <iostream>
#include <limits>
using namespace std;
int main()
{
int x;
cout << "5 + 4 = ";
while(!(cin >> x)){
cout << "Error, please try again." << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
if (x == (5 + 4)){
cout << "Correct!" << endl;
}
else{
cout << "Wrong!" << endl;
}
return 0;
}
How can I check if the user inputs a valid integer? In this program I wrote above, if the user inputs 9, it should be correct, however, if the user inputs 9a for example, it should return an error, but it doesn't for some reason. How can I correct it?
How I did it using cin.peek()
#include <iostream>
#include <limits>
#include <stdio.h>
using namespace std;
int main()
{
int x;
bool ok;
cout << "5 + 4 = ";
cin >> x;
while(!ok){
cin >> x;
if(!cin.fail() && (cin.peek() == EOF || cin.peek() == '\n')){
ok = true;
}
else{
cout << "Error, please try again." << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
}
if (x == (5 + 4)){
cout << "Correct!" << endl;
}
else{
cout << "Wrong!" << endl;
}
return 0;
}
You could read a string, extract an integer from it and then make sure there's nothing left:
std::string line;
std::cin >> line;
std::istringstream s(line);
int x;
if (!(s >> x)) {
// Error, not a number
}
char c;
if (s >> c) {
// Error, there was something past the number
}
bool isIntegerNumber(const std::string& string){
std::string::const_iterator it = string.begin();
int minSize = 0;
if(string.size()>0 && (string[0] == '-' || string[0] == '+')){
it++;
minSize++;
}
while (it != string.end() && std::isdigit(*it)) ++it;
return string.size()>minSize && it == string.end();
}
You have a line oriented input, so you should probably be using
getline. Something like:
bool
getIntFromLine( std::istream& source, int& results )
{
std::string line;
std::getline( source, line );
std::istringstream parse( source ? line : "" );
return parse >> results >> std::ws && parse.get() == EOF;
}
should do the trick.
Using this, your loop would be:
while ( !getIntFromLine( std::istream, x ) ) {
std::cout << "Error, please try again." << std::endl;
}
Note that this technique also means that you don't have to worry
about clearing the error or resynchronizing the input.
For the reason this happens, take a look at this link:
Extracts and parses characters sequentially from the stream to
interpret them as the representation of a value of the proper type,
which is stored as the value of val. Internally, the function accesses
the input sequence by first constructing a sentry object (with
noskipws set to false). Then (if good), it calls num_get::get (using
the stream's selected locale) to perform both the extraction and the
parsing operations, adjusting the stream's internal state flags
accordingly. Finally, it destroys the sentry object before returning.
Then observe the behavior if you attempt something like this:
int x = 0;
cin >> x;
std::cout << x << std::endl;
std::cout << cin.good() << std::endl;
g++-4.8 -std=c++11 -O3 -Wall -pedantic -pthread main.cpp && echo "900a100" | ./a.out
// Output:
// 900
// 1
If you input "a100" instead, it outputs:
0
0
try this:
std::string input;
std::cin >> input;
if ( std::all_of(input.begin(), input.end(), std::isdigit) )
{
//input is integer
}
Refer this :
C++ Fix for checking if input is an integer
One I have seen that works for some situations is:
Read the input as string. cin >> str
Decode to number: atoi, or sscanf, or stringstream, etc.
print the number into a string (using sprintf or stringstream)
check if its equal to read string. (using strings ==, not char*)
Quick and simple to do. Uses the Cin>>str word breaking rules, accept negative numbers, rejects overflowing numbers. But it does reject "+10", which in somesituations you are happy wiht, and in some you are not.
If you can use C++11 (and your compiler has full regex support), you can also use the <regex> library:
#include <iostream>
#include <limits>
#include <regex>
#include <string>
#include <utility>
int main()
{
std::string line;
std::pair<int, bool> value = std::make_pair(0, false);
std::cout << "5 + 4 = ";
while (!value.second)
{
while (!std::getline(std::cin, line))
{
std::cout << "Error, please try again." << std::endl;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
if (!std::regex_match(line, std::regex("(\\+|-)?[[:digit:]]+")))
{
std::cout << "Error, please try again." << std::endl;
}
else
{
value = std::make_pair(std::stol(line), true);
}
}
if (value.first == (5 + 4))
{
std::cout << "Correct!" << std::endl;
}
else
{
std::cout << "Incorrect!" << std::endl;
}
return 0;
}