Please can you check this code? What's wrong with try/catch/throw?
#include<iostream>
using namespace std;
int get_input();
int main() {
int number, base_in, base_out;
bool pass = 1;
while(pass) {
double number, base_in, base_out;
try {
cout << "What's your number? ";
number = get_input();
pass = 0;
}
catch(problem_type()) {
cout << "Please, write inputs should be integer" << endl;
}
}
return 0;
}
int get_input(bool target = 1) {
double n;
cin >> n;
if(n != (int)n) throw problem_type();
if(target) {
if(n<1) throw problem_type();
}
return (int)n;
}
You catch by type. Like
catch(const problem_type&){ }
That is, if problem_type is type. I see no definition anywhere…
When an exception is throw you'll get a in memory object with info about the exception... so it's necessary to take it as catch( const Type& error )
Why is it as a reference? Think of the possible caotic state that would be on memory on some situations, so MAKE a copy of would add complications and processing time, you could loose vital info. So that's why we take it as a reference.
Just 'point' to original piece of data.
Related
I have one doubt regarding error handling...
If a function throws an exception and that exception isn't caught in main program will crash badly.
My question is why doesn't this program crash? If an exception is thrown from Test function enterNumber will throw an exception too even though it wasn't caught?
Shouldn't every function that might throw an exception be put in a try-catch block just in case it throws it?
1°
#include <iostream>
#include <stdexcept>
void Test(int number) {
if(number < 0)
throw std::domain_error("Number is negative");
}
int enterNumber() {
int number;
std::cout << "Enter a number: ";
std::cin >> number;
Test(number);
return number;
}
int main() {
try {
int number = enterNumber();
std::cout << "Entered number: " << number;
}
catch(std::domain_error e) {
std::cout << e.what();
}
return 0;
}
I thought it should be written like this:
2°
void Test(int number) {
if(number < 0)
throw std::domain_error("Number is negative");
}
int enterNumber() {
int number;
std::cout << "Enter a number: ";
std::cin >> number;
try {
Test(number);
}
catch(...) {
throw;
}
return number;
}
int main() {
try {
int number = enterNumber();
std::cout << "Entered number: " << number;
}
catch(std::domain_error e) {
std::cout << e.what();
}
return 0;
}
If someone could explain how the function enterNumber throws an exception in case Test throws it? (case 1°)
Thank you :)
You do not need to catch an exception from the function that called the function that caused the exception. Indeed, best practice is to catch the exception as far as possible (but no further) from the site where the exception was thrown, as it is only at higher levels of the program that you have sufficient information to produce meaningful error messages, and/or to deal with the exception in other ways. However, the exception should be caught at some level of the program, or the program will terminate in an uncontrolled manner.
This post treats the same error, but the poster isn't have trouble with a void function.
This post concerns the "void" type of function, but the poster is advised to change the function type to "string", which does not help my case.
My code executes fine, except for a literal "0" at the end of the output. When I change the function type to "void", I am met with the above error.
I have been through the tutorial on this numerous times, and have searched thoroughly, yet have been unable to resolve this issue.
//my code
#include <iostream>
using namespace std;
int intervalcountdown (int a, int b) {
for(a; a>0; a = a - b) {
cout << a;
if(a<=b) {
break;
}
cout << ",";
}
cout << ".";
return 0;
}
int main () {
cout << intervalcountdown(20,3);
return 0;
}
Just don't print what you don't want.
#include <iostream>
using namespace std;
void intervalcountdown (int a, int b) { // change return type to void
for(; a>0; a = a - b) { // meaningless a is removed
cout << a;
if(a<=b) {
break;
}
cout << ",";
}
cout << ".";
// remove the return statement because the return type is now void
}
int main () {
intervalcountdown(20,3); // remove extra printing
return 0;
}
I would like to take the return value from the function on the top and then do something with it in the function on the bottom. What should I put in the bottom function to use the value that was returned from "loadVectorWithReturn"
I do realize that I could create a new variable and store it there for later recall but I am trying to do more complicated things now.
Thank you
double vectors1::loadVectorWithReturn() {
vectors1 v1;
for (int i = 0; i <= 10; i++) {
v1.value.push_back(i);
cout << v1.value[i] << ", ";
}
cout << endl;
cout << v1.value[5] << endl;
return v1.value[5];
}
double doSomethingWithVectorReturn(TAKE IN VALUE FROM loadVectorWithReturn) {
//do something with v1.value[5];
}
If you are saying, "I don't want to make a global variable for v1", you could do this.
double vectors1::loadVectorWithReturn() {
vectors1 v1;
for (int i = 0; i <= 10; i++) {
v1.value.push_back(i);
cout << v1.value[i] << ", ";
}
cout << endl;
cout << v1.value[5] << endl;
return v1.value[5];
}
double vectors1::doSomethingWithVectorReturn() {
int returned = loadVectorWithReturn();
//Do something with returned.
}
Note: the "vectors1::" in front of "doSomethingWithVectorReturn" allows "doSomethingWithVectorReturn" to use the "loadVectorWithReturn" function.
Keep in mind that if you are only using the "returned" value one time (or multiple although that can be slower in many cases), you could skip setting the variable and just use "loadVectorWithReturn()" in place of it.
Example (Simply cout's the value):
double vectors1::doSomethingWithVectorReturn() {
cout << loadVectorWithReturn();
}
I am feeling like you are needing this because you will use loadVectorWithReturnlater within doSomethingWithVectorReturn in some point.
If this is the situation we can use:
#include <iostream>
#include <functional>
struct A
{
int fooA() const
{
return 5;
}
};
void doSomethingWithA( std::function<int()> foo )
{
std::cout << foo();
}
int main()
{
A a;
doSomethingWithA([a]()
{
return a.fooA();
});
}
The following code throws the exception perfectly fine in Visual Studio 2010:
#include <iostream>
#include <cmath>
using namespace std;
int perfectSquare(double sq, int nu);
int main()
{
double num;
double squareRoot;
int perfectSq;
cout << "Enter the a number: ";
cin >> num;
try
{
squareRoot = sqrt(num);
perfectSq = perfectSquare(squareRoot, num);
cout << "The square root is: " << perfectSq << endl;
}
catch(char * exceptionString)
{
cout << exceptionString;
}
cout << "BYE." << endl;
// system("PAUSE");
return 0;
}
int perfectSquare(double sq, int nu)
{
int temp = sq;
if (sq != temp) //clever test; if square root IS NOT an INT
{
throw "not a perfect square.\n";
}
else
{
return sq;
}
}
However, in Xcode, it will not resume and it keeps hitting a breakpoint in the debugger. For example if I inpute 33 (not a perfect square), the following error is displayed:
libc++abi.dylib: terminate called throwing an exception
(lldb)
It should "throw" this line: "not a perfect square." and the program should terminate (like in VS 2010). I don't want to enable exception breakpoints in Xcode as I just want the program to run all the way to the end without debugging.
Thanks to all.
What you are throwing is a string literal, which in XCode seems to be a const char*, not a char*
You are not actually throwing a char *, you are throwing a const char *. Change the exception catch to
catch(const char * exceptionString)
and it should work.
All literal strings in C++ are equivalent to pointers to a constant string, i.e. const char *.
I basically have exp>=level*10 in an else if expression, where level is a variable and 10 is a constant number. The code compiles completely fine without any errors, and it even worked after being compiled, until recently. now, whenever it compiles and executes, it gives me an error saying "invalid null pointer" and it conveniently tells me that the problem comes from the included file xstring (VS2010 includes it in new projects) on line 930.
Is there a way to force to program to read it as the multiplication operator instead of a null pointer?
EDIT: Here is my full code, please note that this is a protype created to ensure that it will work and was done prior to me realizing I can use derived classes for this. also note that I tried removing using namespace std to see if that was the problem.
#include "stdafx.h"
#include <iostream>
#include <sstream>
class player {
public:
std::string name;
int hp;
int attack;
int strength;
int defense;
void reward(int gold, int exp) {
player::gold += gold;
player::exp += exp;
player::levelHandler();
}
int dataQuery(std::string query) {
if (query == "equipment")
return helm, armour, greaves;
else if (query == "gold")
return gold;
else if (query == "exp")
return exp;
else if (query == "level")
return level;
else return 0;
}
private:
int helm;
int armour;
int greaves;
int level;
int gold;
int exp;
std::string levelHandler() {
if (level==0) {
level=1;
}
else if (exp>=(10*level)) { //causes problem due to * being mistaken as a
//null pointer.
int previousLevel = level;
level += 1;
levelHandler();
return 0;
};
return 0;
};
} hero;
class enemy {
public:
std::string name;
int hp;
int attack;
int strength;
int defense;
private:
int helm;
int armour;
int greaves;
int level;
int goldReward;
int expReward;
int dataQuery(std::string query) {
if (query == "equipment")
return helm, armour, greaves;
else if (query == "gold")
return goldReward;
else if (query == "exp")
return expReward;
else if (query == "level")
return level;
else return 0;
}
};
int main()
{
std::cout << "Please enter your character's name..." << std::endl;
std::cin >> hero.name;
std::cout << "Welcome to RPG Battle Simulation, " << hero.name << "!" << std::endl;
hero.reward(100, 0); //problem is either this line, or the function's call to levelHandler, as this is where the program terminates.
std::cout << "You are beginning your journey as a level " << hero.dataQuery("level") << " character." << std::endl;
std::cout << "Here is " << hero.dataQuery("gold") << " gold to get you started." << std::endl;
return 0;
};
The following is an excerpt of xstring that is causing the problem. the problem comes from _DEBUG_POINTER(_Ptr); (line 930)
_Myt& assign(const _Elem *_Ptr)
{// assign [_Ptr, <null>)
_DEBUG_POINTER(_Ptr);
return (assign(_Ptr, _Traits::length(_Ptr)));
}
This program reproduces your problem (when compiled with MSVC with runtime that supports debugging):
#include <string>
#include <iostream>
int main()
{
using namespace std;
string s = 0;
cout << s << endl;
}
The problem is that a std::string is initialized with a nullpointer.
EDIT: oh, forgot to mention, solution – simply don’t do that.
Cheers & hth.,