How to make a try catch recursion in a switch statement iterative? - c++

I am trying to make a function that looks like below. I want to make it iterative, but I am not sure since I need to keep all paths open.
someFunction( parameters)
{
//do stuff
switch( thing )
case: one
if (something true)
{
try { someFunction( different parameters ) } catch(...) { throw }
case: two
//if else with the else being a throw exception.
case: three
// same
case: four
...
default
return some value

I didnt understand very well ur question, but i will try to help!
How to use EXCEPTIONS:
...
try
{
if(b == 0)
throw("A number cannot be devided by zero!\n");
c = a/b
}
catch(string error)
{
cout << "ERROR: "<< error << endl;
}
return c
...
You could use it in a switch statement, after the catch i will return to the case.
switch(c)
{
case 0:
...
try { ... throw();}
catch() { ... error treatment}
...
break;
case 1:
...
}

Related

Else for multiple if's

Is it possible to make multiple if's and one else for all of them without using the bool variable? I'm talking about something that works like this:
bool triggered = 0;
if (condition)
{
//code
triggered = 1;
}
if (condion2)
{
//code
triggered = 1;
}
if (!triggered)
{
//code
}
So if none of these if's happened - something happens. In pseudo-code I would write it like this:
{
if()
{
}
if()
{
}
}
else
{
}
Is there a possibility to make something similar?
No, you can't do it like that. You can do:
if (condition1 || condition2) {
if (condition1) {
//code
}
if (condition2) {
//code
}
} else {
// code
}
But this means you have to test condition1 and condition2 twice. And if there are lots of conditions, the first if will be very long.
I find your code with the triggered variable preferable. Often, there's already a variable that serves the purpose. For instance, form validation code often looks something like this:
std::string errors;
if (field1 is invalid) {
errors += "Field1 is invalid\n";
}
if (field2 is invalid) {
errors += "Field 2 is invalid\n";
}
if (errors == "") {
// process the form
} else {
// display error message
}

how to use enum inside a switch condition

The following code uses a switch with enum. The main program passes the argument correctly to the function, but the correct switch line is not executed. Can you advise why it is not entering the switch conditions?
enum MyEnum {
Enum1 = 1,
Enum2 = 0x0D
};
bool compute(MyEnum code) {
switch(code) {
Enum1: return true;
Enum2: return false;
};
cout << "why here??" << endl; // this line is getting printed for both inputs
return false;
}
int main() {
cout << "compack=" << compute((MyEnum)1) << endl; // printed "0"
cout << "compack=" << compute((MyEnum)13) << endl; // printed "0"
}
I checked the other questions related to switch and enum (eg 3019153), but cant figure out the bug.
You are missing the case keyword:
switch(code) {
case Enum1: return true;
case Enum2: return false;
};
switch(code)
{
case Enum1: return true;
case Enum2: return false;
};
You forgot to write case
switch(code)
{
case Enum1: return true;
case Enum2: return false;
};
A generic switch is like:
switch(var)
{
case val1:
foo();
break;
case val2:
bar();
break;
default:
error();
};
You forgot case there..
switch(code)
{
case Enum1:
//do something
break;
case Enum2:
//do something
break;
};
Okay, so others have answered that you are missing the case keyword. What hasn't been explained, though, is why the original code compiled. That's because without the case keyword, it was treated as a goto label. In fact, this compiles:
switch (i) {
if (j == 3) {
case 1:;
L1:;
} else {
goto L1;
case 2:;
}
}
Note that the j==3 is actually dead code. It can never be executed. For an actual useful application of this, see Duff's device. By the way, compiling with full warnings enabled would have warned you about an unused goto label, at least with g++ and clang++ (-Wall -Wextra -pedantic).

switch between if/else blocks on error

I'm looking for a way to switch between an if and an else block when an error occurs. For example:
cout << "Enter 1 or 2 as your choice...";
cin >> choice;
if(choice==1) {
//do something here
//if error occurs....
} else if(choice==2) {
//switch to this else block
}
I've played around with try/throw/catch but it appears that the catch has to follow the try statement. Any ideas/suggestions would be appreciated!
When I come across this situation, I create a separate function with the code wanted in the else block. Then I call the function whenever needed (if an error occurs, and in the else block).
Looks like you could just not have an "else":
int error = 0;
if( choice==1 ) {
// Something happens
error = 1;
}
if( error == 1 || choice == 2 ) {
// Do things
}
You really want to split that in to two different conditional blocks. After all, you don't really mean "else".
if(choice==1)
{
//if error occurs....
}
if(choice==2 || error)
{
//switch to this block
}

Fixing a weird write to file bug in c++

i got this really wierd problem, i'm writing my results to an output file, i use functions A B and C i activate them in that order, the results in the file is printed in a different order, first from A than from C and after that from B. i just can't understand why the results printed in a different order than the activation order. thanx.
the code :
void Manager::AddCommand(Command* com, ofstream &ResultFile)
{
if (com != NULL)
{
if (com->ValidCommand(ResultFile) == true)
commands.push_back(com);
else
delete com;
}
}
bool Command::ValidCommand(ofstream &Result) const
{
if(func<PrintCityCouncilList || func >HireEmployee){
Result << "Command:Failed activating function - invalid function number\n";
return false;}
if ((func == Command::PrintDepartmentEmployees) || (func == Command::PrintDepartmentExpenses) || (func == Command::PrintDepartmentStatistics)){
if(dept<Employee::Engineering ||dept>Employee::Sanitation )
{
Result << "Command:Failed activating function - invalid department number\n";
return false;
}
}
return true;
}
void Manager::ActivateCommand(Command* com, ofstream &Result)
{
if(com != NULL)
{
switch(com->GetFunction())
{
case (Command::PrintCityCouncilList): pcc->PrintCityCouncilDetails(Result);
break;
case (Command::PrintDepartmentEmployees):ActivatePrintDeprtEmployees(com->GetDepartment(), Result);
break;
case (Command::PrintEmployeeSalary):ActivateEmployeeSalary(com->GetId(), Result);
break;
case (Command::PrintDepartmentExpenses):ActivateDeprtExpenses(com->GetDepartment(), Result);
break;
case (Command::PrintCityCouncilExpenses): pcc->AllExpenses (Result);
break;
case (Command::PrintDepartmentStatistics):ActivateDeprtStatistics(com->GetDepartment(), Result);
break;
case (Command::FireEmployee): pcc->RemoveEmployeeFromCC(NULL,com->GetId(),Result);
break;
case (Command::HireEmployee): pcc->AddEmployeeToCC(com->GetId(),com->GetPrivateName(),com->GetSurName(),com->GetDate(),com->GetAddress(),com->GetDepartment(), com->GetStatus(),com->GetSalary(),com->GetPositionPercent(),com->GetPhoneNum(), Result);
break;
default:Result<<"Manager:Failed Activating command - invalid function"<<endl;
break;
}
}
}
void Manager::ActivateCommandsList(ofstream &Result)
{
Command* tmp = NULL;
if (commands.empty() == false)
{
list<Command*>::iterator iter = commands.begin();
while (iter != commands.end())
{
tmp = (Command*)(*iter);
ActivateCommand(tmp,Result);
iter++;
}
}
}
Ok here's the deal, your code maybe having some difficulties if you are running it in visual stdio. You see, it has some bugs when it tries to optimize your code. Turn optimization off. Also flush your stream, that's done when putting endl in cout and \n in printf. There is another possibility and it is Stack-Corruption or Heap-Corruption. Check to see if your dynamic objects are referenced within their boundaries.
As long as you don't send the code, like my friend just said we should consult the crystall ball.
My guess is that if this is homework, you are not having a threading issue. Have you tried to flush the output stream from A, B, and C? That might solve your problem.

return statements when doing Extract Method

Let's say you have a very long method, like this:
int monster()
{
int rc = 0;
// some statements ...
if (dragonSlayer.on_vacation()) {
cout << "We are screwed!\n";
if (callTheKing() == true)
return 1;
else
return 2;
} else {
cout << "We are saved!\n";
slayTheDragon();
}
// rest of long method...
return rc;
}
and I'm working on skeletonizing the code. I want to extract the dragon slaying part to
int handleDragon() {
if (dragonSlayer.on_vacation()) {
cout << "We are screwed!\n";
if (callTheKing() == true)
return 1;
else
return 2;
} else {
cout << "We are saved!\n";
slayTheDragon();
}
return 0; // ?
}
and replace the code in monster() with a call to handleDragon().
But there is a problem. There is a return statement in the middle of that part. If I keep the part where the return code of handleDragon() is handled, it will keep the litter in the big method.
Besides using exceptions, is there an elegant and safe way to refactor this piece of code out of the monster method? How should these types of situations be handled?
Return 0 from the handleDragon method if the dragon slayer is available:
int handleDragon() {
if (dragonSlayer.on_vacation()) {
cout << "We are screwed!\n";
if (callTheKing() == true)
return 1;
else
return 2;
} else {
cout << "We are saved!\n";
slayTheDragon();
return 0;
}
}
Then back in the monster method, if the return value was greater than zero, return that value, otherwise carry on:
// some statements ...
int handleDragonResult = handleDragon();
if (handleDragonResult > 0) {
return handleDragonResult;
}
// rest of long method...
You should also document the handleDragon method, to explain the value that gets returned.
enum DragonHandled { DHSuccess, DHKing, DHNoKing };
inline DragonHandled askForKing()
{
if (callTheKing())
return DHKing;
else
return DHNoKing;
}
DragonHandled handleDragon()
{
if (dragonSlayer.on_vacation()) {
cout << "We are screwed!\n";
return askForKing();
}
cout << "We are saved!\n";
slayTheDragon();
return DHSuccess;
}
int monster()
{
some_statements(...);
DragonHandled handled = handleDragon();
if( handled != DHSuccess )
return handled; // enum to int is an implicit cast
return more_statements(...);
}
Except for a function that returns an actual signed number, I would not return int. If the result has a meaning, define that meaning properly (that is: an enum).
A function does something, and whatever it does, should be visible in its name. So there should be a verb in a function's name (handledragon(), callTheKing()). monsters isn't a verb, it isn't something you can do. If I see an identifier monsters, I'd think it's a container for monsters.
Checking if(x == true) is just useless noise, since if(x) is terser, simpler and just as true.
Couldn't you do this:
int handleDragon() {
int rc = 0;
if (dragonSlayer.on_vacation()) {
cout << "We are screwed!\n";
if (callTheKing() == true)
rc = 1;
else
rc = 2;
} else {
cout << "We are saved!\n";
slayTheDragon();
}
return rc;
}
and then:
int monster()
{
int rc = 0;
// some statements ...
rc = handleDragon();
// rest of long method...
return rc;
}
or if you want to do something with the return code:
int monster()
{
int rc = 0;
// some statements ...
int handleDragonReturnCode = handleDragon();
if(handleDragonReturnCode == 0) {
// do something
}
else {
// do something else
}
// rest of long method...
return rc;
}
Is this what you want? On a general note, avoid using magic numbers like 1 and 2 for your return codes. Use constants, #define, or enum.
Concerning return, try to have one exit point from your function. As you have found out, having multiple return statements can make refactoring hard (as well as understanding the logic unless it's really simply).
The question was about the strategy so I think the answer by Richard Fearn is a good one.
To make it into a refactoring pattern it would look something like:
Context: A section in the middle of a larger method is to be extracted.
Problem: The section contains return statements.
Solution:
Extract the code to a new method returning the same type as the larger method.
Find a value of that type that does not mean anything. Call that value CONTINUE.
Add a statement at the end of the new method that returns CONTINUE.
In the larger method test the return value from the new method for CONTINUE. If it is not then return that value.
This would be the principal approach. As the next step you could refactor the return values from the new method to something more meaningful (like in the answer from sbi). And you'd have to find a way to handle the case where the return type isn't a scalar or simple type, returning a NULL object or some such.