It sounds like you're trying to overload a function:
void foo(int i)
{
// stuff
}
void foo(float f)
{
// stuff
}
int main(void)
{
int i = 10;
float f = 1.0f;
foo(i); // calls foo(int)
foo(f); // calls foo(float)
}
If you want int
-special behavior and then something else in all other cases, you can use templates:
template <typename T>
void foo(T t)
{
// T is something
}
template <>
void foo(int i)
{
// for int's only
}
int main(void)
{
int i = 10;
float f = 1.0f;
double d = 2.0;
foo(i); // calls specialized foo
foo(f); // calls generic foo
foo(d); // calls generic foo
}
According to your comment ("Task at hand is a simple program: Take two user inputted integers and add them. Restrict input to integer only. I can do it in Python and I am thinking too along those lines. if num1 != type(int): print "You did not enter an integer, please enter a integer." else: continue"), you want something like this:
#include <iostream>
int main(void)
{
int i;
std::cin >> i;
if (std::cin.fail())
{
std::cout << "Not valid!" << std::endl;
}
else
{
// ...
}
}
This will notify invalid input such as "@#$", "r13", but does not catch cases such as "34fg", "12$#%", because it will read the int
, and stop at "fg" and "$#%", respectively.
To check that, you will have to read in a line of input, and then try to convert that line into the type you want. (Thanks, litb). That means your question is more like this question:
#include <iostream>
#include <sstream>
#include <string>
int main(void)
{
std::string input;
std::getline(std::cin, input);
std::stringstream ss(input);
int i;
ss >> i;
if (ss.fail() || !(ss >> std::ws).eof())
{
std::cout << "Not valid!" << std::endl;
}
else
{
// ...
}
}
This does the following: get input, and put it into a stringstream
. Then after parsing the int
, stream out any remaining white space. After that, if eof
is false, this means there are left-over characters; the input was invalid.
This is much easier to use wrapped in a function. In the other question, the cast was re-factored away; in this question we're using the cast, but wrapping the input along with it.
#include <iostream>
#include <sstream>
#include <string>
bool parse_int(int& i)
{
std::string input;
std::getline(std::cin, input);
std::stringstream ss(input);
ss >> i;
return !(ss.fail() || !(ss >> std::ws).eof());
}
int main(void)
{
int i;
if (!parse_int(i))
{
std::cout << "Not valid!" << std::endl;
}
else
{
// ...
}
}
Or more generically:
#include <iostream>
#include <sstream>
#include <string>
template <typename T>
bool parse_type(T& t)
{
std::string input;
std::getline(std::cin, input);
std::stringstream ss(input);
ss >> t;
return !(ss.fail() || !(ss >> std::ws).eof());
}
int main(void)
{
int i;
if (!parse_type(i))
{
std::cout << "Not valid!" << std::endl;
}
else
{
// ...
}
}
This let's you parse other types with error checking.
If you're okay with exceptions, using lexical_cast
(either from boost, or "faked", see the other question linked in-code [same as above link]), your code would look something like this:
#include <iostream>
#include <sstream>
#include <string>
/* Faked lexical-cast from question:
http://stackoverflow.com/questions/1243428/convert-string-to-int-with-bool-fail-in-c/
*/
template <typename T>
T lexical_cast(const std::string& s)
{
std::stringstream ss(s);
T result;
if ((ss >> result).fail() || !(ss >> std::ws).eof())
{
throw std::bad_cast("Bad cast.");
}
return result;
}
template <typename T>
T parse_type(void)
{
std::string input;
std::getline(std::cin, input);
return lexical_cast<T>(input);
}
int main(void)
{
try
{
int i = parse_type<int>();
float f = parse_type<float>();
}
catch (const std::exception& e)
{
std::cout << e.what() << std::endl;
}
}
I don't think boost has a no-throw version of lexical cast, so we can make a true/false rather than exception version of this code by catching bad_cast
's, as follows. Once again, this works with either boost
or a custom lexical cast. (Anything that does a lexical cast and throws bad_cast
):
#include <iostream>
#include <sstream>
#include <string>
/* Faked lexical-cast from question:
http://stackoverflow.com/questions/1243428/convert-string-to-int-with-bool-fail-in-c/
*/
template <typename T>
T lexical_cast(const std::string& s)
{
std::stringstream ss(s);
T result;
if ((ss >> result).fail() || !(ss >> std::ws).eof())
{
throw std::bad_cast("Bad cast.");
}
return result;
}
template <typename T>
bool parse_type(T& t)
{
std::string input;
std::getline(std::cin, input);
try
{
t = lexical_cast<T>(input);
return true;
}
catch (const std::bad_cast& e)
{
return false;
}
}
int main(void)
{
int i;
if (!parse_type(i))
{
std::cout << "Bad cast." << std::endl;
}
}
Now it's back to a bool
result, except we avoid code duplication by using existing lexical_cast
functions.
You can of course choose which method you would like to use.