Reputation:
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.
Upvotes: 0
Views: 4504
Reputation: 20730
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"
}
Upvotes: 0
Reputation: 409176
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`
}
Upvotes: 3
Reputation:
#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;
}
Upvotes: 0
Reputation: 1720
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.
Upvotes: 1