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;
}
Related
I'm trying to create a command menu where the user will be able to perform as many commands as he/she wants until pressing "q" which will end the loop. I think I have everything I need to do this except I realized mid-way that my professor asked to use string. When I included string into the program, I began to get error messages saying "could not convert string to bool" wherever there was a while or if statement. What can I do to fix this problem and get my program working. Thanks in advance.
#include <iostream>
#include <string>
using namespace std;
int main()
{
char option;
char number=0;
string s;
string n;
string p;
string q;
char number2;
cout << " Please enter a number: "<< endl;
cin >> number;
do {
cout << " Please enter a command: " << endl;
cout << " s- square the number " << endl;
cout << " n- add the number and (number +1) " << endl;
cout << " p- add the number and (number -1) " << endl;
cout << " q- quit" << endl;
cin >> option;
if (option=s) {
s= number*number;
cout << "Square of this number is : " << s;
}
else if ( option=n){
number2= number+1;
n= number+number2;
cout << "Sum of" << number << "+" << number2 << "is: " << n;
}
else if (option=p) {
number2= number-1;
p= number+number2;
cout << "Sum of" << number << "+" << number2 << "is" << p;
}
else if (option=q)
cout << "Terminating Program";
} while(option);
return 0;
}
you're assigning in the if and else if rather than comparing.
if (option=s) {
should be
if (option=='s') {
note the double =
Also, you need to put single quotes (') around the character choice.
It's a common mistake that even experienced developers make.
These declarations
char number=0;
string s;
string n;
string p;
string q;
char number2;
should all be int
int number=0;
int s;
int n;
int p;
int q;
int number2;
Let me answer as if I were who will evaluate your homework. You have several issues here:
You are asked to use string. Avoid the use of char and string together.
char option; // professor asked to use string: (-1) point
string option; // ok
When you use a single =, like in option="a", you are assigning the value "a" to the variable option. But in the if-else statements you want to compare, so you should use the == comparison operator. Also, you can't compare a char with a string.
if(option = "a") // error: expression must have bool type: (-2) points
if(option == 'a') // error: no operator "==" matches std::string == char; (-2) points
if(option == "a") // ok
You use while(option), but option is declared as a char, not as a bool. Replace this line to while(option!="q") to finish when you enter q.
while(option); // error: expression must have bool type; (-2) points
while(option != "q"); // GOOD!
Also, your program will finish when you scape from the while-statement; so, try to put the "Terminating Program" message after this.
You do not need to declare such many variables (s, n, p, q, number2). Try to use temporary variables inside each scope, for example:
if (option=="s")
{
cout << "Square of this number is : " << number*number << endl;
}
else if ( option=="n")
{
int number2= number+1;
cout << "Sum of " << number << "+" << number2 << " is : " << number+number2 << endl;
}
In the form you write this code, every time you type a new option you will obtain an output like:
Sum of 10+11 is : 21 Please enter a command:
This is ugly to me (-1 point). Try to put a newline (<< endl;) after every cout lines.
Finally, what if I type any other letter not listed in the menu? I would expect a message like Enter a valid option (-1 point).
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.
Hi I'm new with c++ and am having a hard time with creating a code to convert currencies. Could you please look at my current code and give any suggestions. the first goal is first to determine the type of currency. then the amount. finally the conversion.
#include <iostream>
#include <string>
using namespace std;
int main()
{
//declaring constant conversion values of currency per dollar
const float ColombianPeso = 2000;
const float MexicanPeso = 13.25;
const float ArgentinePeso = 8.4;
const float VenesuelanBolivar = 6.28;
const float ChileanPeso = 593.719;
//designing statement to allow user to input curency type
char currency[] = "show me the money (USDollar, MexicanPeso, ArgentinePeso, ColombianPeso, VenesuelanBolivar, or ChileanPeso):\n";
char answer1[17];
cout << currency;
cin >> answer1;
//designing statement to imput amount
float amount = 0;
cout << "enter amount:\n";
cin >> amount;
//creating if/else statement to convert for diffent money values
if (answer1 == USDollar)
cout << "number of Colombian Pesos:\n" << amount * ColombianPeso;
cout << "number of Venesuelan Bolivars:\n" << amount * VenesuelanBolivar;
cout << "number of Mexican Pesos:\n" << amount * MexicanPeso;
cout << "number of Argentine Pesos:\n" << amount * ArgentinePeso;
cout << "number of Chilean Pesos:\n" << amount * ChileanPeso;
else if (answer1 == MexicanPeso)
cout << "number of US Dollars:\n" << amount / MexicanPeso;
else if (answer1 == ColombianPeso)
cout << "number of US Dollars:\n" << amount / ColombianPeso;
else if (answer1 == ArgentinePeso)
cout << "number of US Dollars:\n" << amount / ArgentinePeso;
else if (answer1 == ChileanPeso)
cout << "number of US Dollars:\n" << amount / ChileanPeso;
else if (answer1 == VenesuelanBolivar)
cout << "number of US Dollars:\n" << amount / VenesuelanBolivar;
else
cout << "try again with VenesuelanBolivar, USDollar, ChileanPeso, ArgentinePeso, ColombianPeso, or MexicanPeso:\n";
return 0;
}
Use a std::string instead of char[]. Also you need to compare to string literals, otherwise it will think those are variables.
std::string answer1;
cin >> answer1;
if (answer1 == "USDollar")
{
// do stuff
}
You're comparing char[] and float, I think you don't want it.
const float ColombianPeso = 2000;
//...
char answer1[17];
//...
cin >> answer1;
//...
else if (answer1 == ColombianPeso)
I'd recommend you to use std::unordered_map; it allows you to in example get float used to conversion when you give a string. Also, it allows modify currency and their ratio in runtime.
#include <string>
#include <unordered_map>
#include <iostream>
#include <stdexcept>
using std::cout;
using std::cin;
using std::clog;
int main(){
std::unordered_map<std::string, float> ratio{
{"ColombianPeso", 2000},
{"MexicanPeso", 13.45},
{"ArgentinePeso", 8.4},
{"VenesueleanBolivar", 6.28},
{"ChileanPeso", 593.719}
};
clog << "Available currency:\n";
for(auto it=ratio.cbegin(); it!=ratio.cend(); ++i)
clog<< '\t' << it->first << ' ' << it->second << '\n';
clog << "Pick one of currency above: ";
std::string choice;
cin >> choice;
try{
auto value=ratio.at(choice); /*if element doesn't exist,
program jumps to the catch*/
float amount;
clog >> "Enter amount: ";
cin >> amount;
cout << value*amount << '\n';
}catch(std::out_of_range&){
clog << "Given currency is not available.\n";
}
}
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;
}
I am a newbie at C++ and I got really stuck at this problem:
When the user enters 2 numbers EX: 1 and 2 than the code has to figure out if the first number is grater or not from the first one, the problem is that the code doesn't bring the true or false as text it brings it as numbers :/
(0= false 1=true)
Code here:
#include <iostream>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
bool GraterFunct(int num1, int num2);
int main(int argc, char** argv)
{
std::cout <<" \n Hello there! This is a test to test how good you are with math. \n ";
std::cout <<" Now enter G or L (Grater, less) to know if a number is grater or less than the number you choose \n ";
char answer [1];
std::cin >> answer;
if(answer == "G" || "g")
{
int number1;
int number2;
std::cout << "You selected: Grater than, \n";
std::cout << "Now type 2 numbers and see which one is grater than the other one. \n" << std::endl;
std::cin >> number1;
std::cout << "Your first number: " << number1 << std::endl;
std::cout << "Select your second number \n";
std::cin >> number2;
std::cout << "The answer is: " << GraterFunct(number1, number2);
}
return 0;
}
bool GraterFunct(int num1, int num2)
{
if(num1 >= num2)
{
{
return true;
}
}
else
{
if(num2 >= num1)
{
return false;
}
}
}
Please help! Thanks in advance!
To format Boolean values as true and false you can set the std::ios_base::boolalpha flag using the std::boolalpha manipulator:
std::cout << std::boolalpha << "true=" << true << " false=" << false << '\n';
In case you are a non-native English speaker like me, you might want to change the formatting of these values. Assuming there are suitable locales installed you can just imbue() into a stream or you can create you own locale with whatever rendering of true and false you want, e.g.:
#include <iostream>
#include <locale>
class numpunct
: public std::numpunct<char>
{
std::string do_truename() const { return "wahr"; }
std::string do_falsename() const { return "falsch"; }
};
int main()
{
std::cout.imbue(std::locale(std::locale(), new numpunct));
std::cout << std::boolalpha << "true=" << true << " false=" << false << '\n';
}
BTW, you always need to verify that you input was successful, e.g.:
if (std::cin >> number1) {
// deal with the successful input here
}
else {
// deal with the wrong input here
}