How to implement throw statement to do a integer value - c++

I have a question that might be very simple to many of you however, I have not found an answer to my question.
I have the program below that is working properly. This code turns a number into a floating number and integer.
Let's say you entered 5.4, the program will give you 5.4 for double and 5 for integer.
Now I need to add a throw catch statement to my program in case the user enters a text instead of a number ("If the conversion fails, throw an exception and allow the user to re-enter the value.").
This is the pseudocode of what I need to do.
try {
if(num ==character)
throw;
cout << "\n The number entered " << num << "invalid, please enter again";
}
catch
{
}
and I implemented something like this, however it did not work. I set the 'a' variable character thinking the user has to enter a text in order to get that message. However it did not work and gave some errors.
try
{
char a;
if (num == a)
throw num;
}
catch(int e)
{
cout << "A number of " << a << " is invalid." << endl;
cout << "Please re-enter a number: ";
cin << num
}
I am very new with this "try,throw,catch" terms. I would be happy if you help me through this, thanks.
#include <C:\\CSIS1600\MyCppUtils.cpp>
#include <iostream>
#include <string>
using namespace myNameSpace;
int main()
{
runner("is running");
cout << "Enter a number : ";
string num;
getline(cin, num);
cout<< "double " << getValidDouble(num) << endl;
cout<< "integer " << getValidInt(num) << endl;
system("pause");
return 0;
}
#include<iostream>
#include<string>
using namespace std;
namespace myNameSpace
{
string num;
void runner(string str)
{
cout <<"runner-3() is running.."<<endl;
}
int getValidInt(string n)
{
int valueint;
valueint=atoi(n.c_str());
return valueint;
}
double getValidDouble(string n )
{
double valuedouble;
valuedouble = atof(n.c_str());
return valuedouble;
}
}

You can use Boost to do a lexical cast. If you have valid input (e.g. 2.54), no exception will be thrown, but with invalid input (e.g. 2???54) the bad_lexical cast is thrown:
#include <boost/lexical_cast.hpp>
try
{
double x1 = boost::lexical_cast<double> ("2.54");
double x2 = boost::lexical_cast<double> ("2???54");
cout << x1 << x2 << endl;
}
catch(boost::bad_lexical_cast& e)
{
cout << "Exception caught - " << e.what() << endl;
}

Related

How do I execute previously executed lines of code in C++

I've started to learn how to code in C++ on my spare time, using different sites and apps that someone who has also learned C++ online provided me with. By now, I know the most basic commands. I've tried an exercise given by a program, and I'm given the information that someone is going on a vacation, and needs to know how much baggage he can bring with him. The limit to how many baggages he can carry is 45, and I have to display a different output if the baggages are below, above or the same as the limit (45 baggages). I have done some coding, and I ended up with this:
#include <iostream>
using namespace std;
int main()
{
const int limit = 45;
int bag;
cout << "Please type your number here: ";
cin >> bag;
string yn;
int keep = 0;
if (limit < bag)
{
cout << "You passed the limit." << endl;
};
if (limit == bag)
{
cout << "Just enough." << endl;
};
if (limit > bag)
{
cout << "You got space." << endl;
};
++keep;
while(keep > 0)
{
int keep = 0;
cout << "Do you want to try another number?" << endl;
cin >> yn;
cout << endl;
if(yn == "yes")
{
int bag = 0;
cout << "Please type your number here: ";
cin >> bag;
if (limit < bag)
{
cout << "You passed the limit." << endl;
};
if (limit == bag)
{
cout << "Just enough." << endl;
};
if (limit > bag)
{
cout << "You got space." << endl;
};
}
else
{
return 0;
}
}
}
I have developed it more than needed -as you can see-, out of my own interest in the problem. I have copied and pasted the 3 IF commands as seen above, and I believe that there is an easier way, with less code, do solve this. What I have thought of is if I could go back and execute some line of code again, either from a line and below (e.g. from line 45 and below), or specific lines of code (e.g. from line 45 to line 60).
I would appreciate it if you thought of another way to solve this problem and posted your code below.
Thank you for your reply.
We all started writing our first C++ program at some time, so allow me to give you some additional feedback:
First of all, avoid writing using namespace std;
Secondly, naming - what is bag, limit, keep and yn? Wouldn't it be much easier to read and understand if they were called bagSize, maximumPermittedBagSize, inputFromUser (you don't really need the variable keep, see below)?
Finally, here is a (roughly) refactored version your program, with duplication removed and comments added.
#include <iostream>
int main()
{
const int maximumPermittedBagSize = 45;
// Loops forever, the user exits by typing anything except 'yes' laster
while(true)
{
std::cout << "Please type your number here: " << std::endl;
//Declare (and initialize!) variables just before you need them
int bagSize = 0;
std::cin >> bagSize;
if (bagSize > maximumPermittedBagSize)
{
std::cout << "You passed the limit." << std::endl;
}
else if (bagSize == maximumPermittedBagSize )
{
std::cout << "Just enough." << std::endl;
}
else
{
std::cout << "You got space." << std::endl;
}
std::cout << "Do you want to try another number?" << std::endl;
std::string inputFromUser = "";
std::cin >> inputFromUser;
std::cout << std::endl;
//Leave the loop if the user does not answer yes
if(inputFromUser != "yes")
{
return 0;
}
}
}
You can simply run a while loop and do like this:
#include <iostream>
using namespace std;
int main()
{
const int limit = 45;
int bag;
string yn = "yes";
while(yn == "yes")
{
cout << "Please type your number here: ";
cin >> bag;
if (limit < bag)
{
cout << "You passed the limit." << endl;
}
else if (limit == bag)
{
cout << "Just enough." << endl;
}
else if (limit > bag)
{
cout << "You got space." << endl;
}
cout << "Do you want to try another number?" << endl;
cin >> yn;
cout << endl;
}
}

Handling exceptions in c++ with typeid

I am improve my abilities at handling error exceptions in c++ and I ran into a problem with a simple test.
Problem: I have made a function called division which gets two numbers from the user. If the the denominator is 0 then an exception should be throw and handled. Also, if the user enters a const char * an exception should be thrown.
Approach: I originally didn't even worry about const char *, but now I am really annoyed that I can't figure out why my condition statements aren't being executed. I could just leave it, but I want to know what is going on.
Code: This is a really simple example so I just attached my code.
#include "stdafx.h"
#include <iostream>
#include <string>
#include <typeinfo>
using namespace std;
template<typename T, typename T2>
double division(T num1, T2 num2)
{
if (num2 == 0)
{
throw num2;
}
return (double) num1 / num2;
}
int main()
{
double num1 = 0.0;
double num2 = 0.0;
try
{
cout << "Enter a number that you would like to divide : " << endl;
cin >> num1;
if (typeid(num1).name() == "const char *" )
{
cout << "I ran" << endl;
throw string("You must enter a number");
}
cout << "Enter the number that you would like to divide the first
number by : " << endl;
cin >> num2;
if (typeid(num2).name() == "const char *" )
{
throw string("You must enter a number");
}
cout << "Result " << division(num1, num2) << endl;
}
catch (string & p)
{
cout << "String error message : " << p << endl;
}
catch (double e)
{
cout << "You cannot divide by " << e << " please try again " << endl;
}
return 0;
}

Exceptional Handling in C++ when user inputs string instead of int

I have a program that requires a user to input a integer number which then has to go to several conditions. When I run the program, if i input a int number it works but if i input a character, the programs just spams the error messages.
I think exception handling might work here but i m not sure how to do.Help out guys!
Here is a part of my prog:
#include <iostream.h>
#include <conio.h>
int i, j, data;
void main()
{
int tempdata;
retry:
cout<<"\n\n Enter the row and coloumn where you want to enter data" <<endl;
cin>>i>>j;
if (i>=1 && i<=9 && j>=1 && j<=9)
{
cout<<"\n Enter your desired value to put in that place"<<endl;
cin>>tempdata;
if(tempdata>=1 && tempdata<=9)
{
data=tempdata;
}
else
{
cout<<"\n Soduku contains numbers from 1 to 9 only.Please try again"<<endl;
goto retry;
}
}
else
{
cout<<"\nEntered row or coloumn is not valid"<<endl;
cout<<"Please try again"<<endl;
goto retry;
}
getch();
}
Instead of a cout, you should indeed use exception handling.
if(tempdata>=1 && tempdata<=9)
{
data=tempdata;
}
else
{
throw std::runtime_error("Soduku contains numbers from 1 to 9 only.Please try again");
}
By putting all this into a function, and not your main, you can then call this function within a try/catch block, and deal properly with the exception: display a pop-up message if you have a GUI, ignore the input, etc. The important part is that, if you ignore it, it is not actually ignored. It is dealt with. Which makes your code a LOT cleaner and maintainable. Example:
try
{
input();
}
catch(std::runtime_error& e)
{
// deal with your invalid input here
}
Also, goto statements are considered bad practice. They can be easily replaced by if/else or while statements, or with return codes in functions. And using them tend to make the code unreadable, difficult to follow.
You need to validate that cin >> is successful before you can then use the value entered. If the user enters data that does not match the expected type, you have to clear the error before you can read new input again.
Try this:
#include <iostream>
#include <limits>
int i, j, data;
bool isNumValid(int data) {
return ((data >= 1) && (data <= 9));
}
void clearInput() {
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
int main() {
int tempdata;
do {
std::cout << "\n\n Enter the row and column where you want to enter data" << std::endl;
if (!(std::cin >> i >> j)) {
std::cout << "\n Please enter numbers only!" << std::endl;
clearInput();
continue;
}
if (!isNumValid(i) || !isNumValid(j)) {
std::cout << "\nEntered row or column is not valid" << std::endl;
std::cout << "Please try again" << std::endl;
continue;
}
std::cout << "\n Enter your desired value to put in that place" << std::endl;
if (!(std::cin >> tempdata)) {
std::cout << "\n Please enter a number only!" << std::endl;
clearInput();
continue;
}
if (!isNumValid(tempdata) {
std::cout << "\n Soduku contains numbers from 1 to 9 only" << std::endl;
std::cout << "Please try again" << std::endl;
continue;
}
data = tempdata;
}
while (true);
std::cin.get();
return 0;
}
Alternatively:
#include <iostream>
#include <limits>
#include <stdexcept>
int i, j, data;
bool isNumValid(int data) {
return ((data >= 1) && (data <= 9));
}
void checkRowColValid(int row, not col) {
if (!isNumValid(row) || !isNumValid(col))
throw std::out_of_range("Entered row or column is not valid");
}
void checkDataValid(int data) {
if (!isNumValid(data))
throw std::out_of_range("Soduku contains numbers from 1 to 9 only");
}
int main() {
int tempdata;
std::cin.exceptions(std::ios_base::failbit);
do {
try {
std::cout << "\n\n Enter the row and column where you want to enter data" << std::endl;
std::cin >> i >> j;
checkRowColValid(i, j);
std::cout << "\n Enter your desired value to put in that place" << std::endl;
std::cin >> tempdata;
checkDataValid(tempdata);
data = tempdata;
}
catch (const std::out_of_range &e) {
std::cout << "\n " << e.what() << std::endl;
std::cout << "Please try again" << std::endl;
}
catch (const std::ios_base::failure &) {
std::cout << "\n Please enter numbers only!" << std::endl;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}
while (true);
std::cin.get();
return 0;
}

std::_throw_out_of_range occurs from nowhere

I'm an absolute beginner in c++. Literally. It's just been a week.
Today I was writing a program to test how many iterations are needed to make a certain number palindromic.
Here is the code:
#include <iostream>
#include <string>
#include <algorithm>
/* This program calculates the steps needed
to make a certain number palindromic.
It is designed to output the values for
numbers 1 to 1000
*/
using namespace std;
class number
{
public:
string value;
void reverse();
};
void number::reverse()
{
std::reverse(value.begin(),value.end());
}
void palindrome(number num)
{
string n=num.value;
number reversenum, numsum, numsumreverse;
reversenum=num;
reversenum.reverse();
numsum.value=num.value;
numsumreverse.value=numsum.value;
numsumreverse.reverse();
int i=0;
while (numsum.value.compare(numsumreverse.value) !=0)
{
reversenum=num;
reversenum.reverse();
numsum.value=to_string(stoll(num.value,0,10)+stoll(reversenum.value,0,10));
numsumreverse.value=numsum.value;
numsumreverse.reverse();
num.value=numsum.value;
i++;
}
cout << "The number " << n << " becomes palindromic after " << i << " steps : " << num.value << endl;
}
int main()
{
number temp;
int i;
for (i=1; i<1001; i++)
{
temp.value=to_string(i);
palindrome(temp);
}
return 0;
}
It goes on smooth for numbers upto 195. But, in case of 196 I get an error.
It says:
terminate called after throwing an instance of 'std::out_of_range'
what(): stoll
I cannot make out what to do. I tried starting from 196 but the error persisted. Any help will be greatly appreciated. :)
UPDATE: This time I tried to do it using ttmath library. But arghs! It again stops at 195 and doesn't even report an error! I might be doing something foolish. Any comments would be appreciated. Here's the updated code:
#include <iostream>
#include <string>
#include <algorithm>
#include <ttmath/ttmath.h>
/* This program calculates the steps needed
to make a certain number palindromic.
It is designed to output the values for
numbers 1 to 1000
*/
using namespace std;
class number
{
public:
string value;
void reverse();
};
void number::reverse()
{
std::reverse(value.begin(),value.end());
}
template <typename NumTy>
string String(const NumTy& Num)
{
stringstream StrStream;
StrStream << Num;
return (StrStream.str());
}
void palindrome(number num)
{
string n=num.value;
number reversenum, numsum, numsumreverse;
reversenum=num;
reversenum.reverse();
numsum.value=num.value;
numsumreverse.value=numsum.value;
numsumreverse.reverse();
ttmath::UInt<100> tempsum, numint, reversenumint;
int i=0;
while (numsum.value.compare(numsumreverse.value) !=0)
{
reversenum=num;
reversenum.reverse();
numint=num.value;
reversenumint=reversenum.value;
tempsum=numint+reversenumint;
numsum.value=String<ttmath::UInt<100> >(tempsum);
numsumreverse.value=numsum.value;
numsumreverse.reverse();
num.value=numsum.value;
i++;
}
cout << "The number " << n << " becomes palindromic after " << i << " steps : " << num.value << endl;
}
int main()
{
number temp;
int i;
for (i=196; i<1001; i++)
{
temp.value=to_string(i);
palindrome(temp);
}
return 0;
}
UPDATE: It's solved. Some research suggested that 196 might be a Lychrel Number. And the result I was getting after implying the ttmath library is just reassuring that my algorithm works. I have tried it out for all the numbers upto 10000 and it gave out the perfect results. Here is the final code:
#include <iostream>
#include <string>
#include <algorithm>
#include <ttmath/ttmath.h>
#include <limits>
/* This program calculates the steps needed
to make a certain number palindromic.
It is designed to output the values for
numbers inside a desired range
*/
using namespace std;
string LychrelList;
int LychrelCount=0;
class number
{
public:
string value;
void reverse();
};
void number::reverse()
{
std::reverse(value.begin(),value.end());
}
template <typename NumTy>
string String(const NumTy& Num)
{
stringstream StrStream;
StrStream << Num;
return (StrStream.str());
}
void palindrome(number num)
{
string n=num.value;
number reversenum, numsum, numsumreverse;
reversenum=num;
reversenum.reverse();
numsum.value=num.value;
numsumreverse.value=numsum.value;
numsumreverse.reverse();
ttmath::UInt<100> tempsum, numint, reversenumint;
int i=0;
while ((numsum.value.compare(numsumreverse.value) !=0) && i<200)
{
reversenum=num;
reversenum.reverse();
numint=num.value;
reversenumint=reversenum.value;
tempsum=numint+reversenumint;
numsum.value=String<ttmath::UInt<100> >(tempsum);
numsumreverse.value=numsum.value;
numsumreverse.reverse();
num.value=numsum.value;
i++;
}
if (i<200) cout << "The number " << n << " becomes palindromic after " << i << " steps : " << num.value << endl;
else
{
cout << "A solution for " << n << " could not be found!!!" << endl;
LychrelList=LychrelList+n+" ";
LychrelCount++;
}
}
int main()
{
cout << "From where to start?" << endl << ">";
int lbd,ubd;
cin >> lbd;
cout << endl << "And where to stop?" << endl <<">";
cin >> ubd;
cout << endl;
number temp;
int i;
for (i=lbd; i<=ubd; i++)
{
temp.value=to_string(i);
palindrome(temp);
}
if (LychrelList.compare("") !=0) cout << "The possible Lychrel numbers found in the range are:" << endl << LychrelList << endl << "Total - " << LychrelCount;
cout << endl << endl << "Press ENTER to end the program...";
cin.ignore(numeric_limits<streamsize>::max(), '\n');
string s;
getline(cin,s);
cout << "Thanks for using!";
return 0;
}
It's a really awesome community. Special thanks to Marco A. :)
UPDATE AGAIN: I've devised my own add() function that cuts the program's dependency on external libraries. It resulted in a smaller executable and faster performance too. Here is the code:
#include <iostream>
#include <string>
#include <algorithm>
#include <limits>
/* This program calculates the steps needed
to make a certain number palindromic.
It is designed to output the values for
numbers inside a desired range
*/
using namespace std;
string LychrelList;
int LychrelCount=0;
string add(string sA, string sB)
{
int iTemp=0;
string sAns;
int k=sA.length()-sB.length();
int i;
if (k>0){for (i=0;i<k;i++) {sB="0"+sB;}}
if (k<0) {for (i=0;i<-k;i++) {sA="0"+sA;}}
for (i=sA.length()-1;i>=0;i--)
{
iTemp+=sA[i]+sB[i]-96;
if (iTemp>9)
{
sAns=to_string(iTemp%10)+sAns;
iTemp/=10;
}
else
{
sAns=to_string(iTemp)+sAns;
iTemp=0;
}
}
if (iTemp>0) {sAns=to_string(iTemp)+sAns;}
return sAns;
}
void palindrome(string num)
{
string n=num;
string reversenum, numsum, numsumreverse;
numsum=num;
numsumreverse=numsum;
reverse(numsumreverse.begin(),numsumreverse.end());
int i=0;
while ((numsum.compare(numsumreverse) !=0) && i<200)
{
reversenum=num;
reverse(reversenum.begin(),reversenum.end());
numsum=add(num,reversenum);
numsumreverse=numsum;
reverse(numsumreverse.begin(),numsumreverse.end());
num=numsum;
i++;
}
if (i<200) cout << "The number " << n << " becomes palindromic after " << i << " steps : " << num << endl;
else
{
cout << "A solution for " << n << " could not be found!!!" << endl;
LychrelList=LychrelList+n+" ";
LychrelCount++;
}
}
int main()
{
cout << "From where to start?" << endl << ">";
int lbd,ubd;
cin >> lbd;
cout << endl << "And where to stop?" << endl <<">";
cin >> ubd;
cout << endl;
string temp;
int i;
for (i=lbd; i<=ubd; i++)
{
temp=to_string(i);
palindrome(temp);
}
if (LychrelList.compare("") !=0) cout << "The possible Lychrel numbers found in the range are:" << endl << LychrelList << endl << "Total - " << LychrelCount;
cout << endl << endl << "Press ENTER to end the program...";
cin.ignore(numeric_limits<streamsize>::max(), '\n');
string s;
getline(cin,s);
cout <<endl << "Thanks for using!";
return 0;
}
You guys here have helped me a lot to find my own way. Thanks everyone. :)
You're overflowing long long since the last two valid values of num.value and reversenum.value are 7197630720180367016 and 6107630810270367917 which, added together, are way above the maximum size of a long long (9223372036854775807 on my machine). That will yield a negative value and spoil your next call to stoll
std::out_of_range is thrown if the converted value would fall out of the range of the result type or if the underlying function (std::strtol or std::strtoll) sets errno to ERANGE.
(reference)
If you're trying to get the next smallest palindrome, you should use another approach like the one I explained here.
You can find a Live Example here
If you prefer to/must continue with your approach you should either do the addition manually on the strings or use a bigint library (again take a look at here and modify the plusOne() function to your liking)
From http://www.cplusplus.com/reference/string/stoll/
If the value read is out of the range of representable values by a long long, an out_of_range exception is thrown.
The ll data type cant handle the string length. My debugger tells me 196 breaks on the value
std::stoll (__str=\"9605805010994805921-\", __idx=0x0, __base=10)
The long long is too small.
You might want to do the addition on the strings themselves, without resorting to a numeric type.

Currency Conversion Program

I'm working on a currency converter program that converts the old system of British pounds, Shillings, and pence, into their new system, which is a type of Decimal Pound. Where 100 pence equals a pound. Here is the code for the program
#include <iostream>
#include <iomanip>
#include <conio.h>
using namespace std;
int calcNum(int pound, int shilling, int pence)
{
pence = pound*240 + shilling*12 + pence;
return pence;
}
int calcNew(int total_pence, double dec_pound)
{
dec_pound = total_pence / 240;
return dec_pound;
}
int main()
{
int pence;
int shilling;
int pound;
const int OLD_POUND = 240;
const int OLD_SHILLING = 12;
double total_pence;
double dec_pound = 0;
double deci_pound;
cout << "Please Enter the Amount of old pounds: ";
cin >> pound;
cout << endl;
if(cin.fail())
{
cout << "That's not a valid number\n";
cout << "This program will terminate on any keypress!";
_getch();
exit(1);
}
cout << "Please Enter the Amount of old shillings: ";
cin >> shilling;
cout << endl;
if(cin.fail())
{
cout << "That's not a valid number\n";
cout << "This program will terminate on any keypress!";
_getch();
exit(1);
}
cout << "Please Enter the Amount of old pence: ";
cin >> pence;
cout << endl;
if(cin.fail())
{
cout << "That's not a valid number\n";
cout << "This program will terminate on any keypress!";
_getch();
exit(1);
}
total_pence = calcNum(pence, shilling, pound);
deci_pound = calcNew(dec_pound, total_pence);
cout << (5, "\n");
cout << "The total amount in decimal pounds is: ";
cout << setprecision(2) << "\x9c" << deci_pound;
_getch();
return 0;
}
When I run this program however, I'm having a bit of a problem. No matter what the number input is, it always says 0 pounds. Just to make sure that the setprecision function at the end wasn't interfering with the code, I had originally set a cout statement with a _getch() after the two functions to show how much deci_pound came out to be calculated to, and once again, it came out as zero. So my issue seems to be somewhere in the functions running the calculations. If someone could help me with this, I would really appreciate it.
Your calcNew(...) function returns an int, make it return a double. Right now it casts to int which involves stripping the decimals.
In your code, dec_pound is set equal to zero, and you're deci_pound = calcNew(dec_pound, total_pence), which divides 0 by 240 = 0.
The order of the parameters when you call both functions is wrong. Your functions are declared and implemented as:
int calcNum(int pound, int shilling, int pence);
int calcNew(int total_pence, double dec_pound);
And then you call them like this:
total_pence = calcNum(pence, shilling, pound);
deci_pound = calcNew(dec_pound, total_pence);