I implemented a Quiz Code and did a short change at the end of it to check if the User answered it correctly.
My if / else looks like this:
if (answer == rightanswer){
rightA = true;
}
else {
rightA = false;
}
return rightA;
I already checked with the debugger that if the correct answer is entered it goes to rightA = true; and to return, so this works finde.
But if i check the value of rightA it's false.
If it's needed, here is the function that i use to call the Quiz:
void gameOver(char field[HEIGHT][WIDTH], char newField[HEIGHT][WIDTH]){ // TODO
bool rightA = false;
showQuizDialog(rightA);
do{
system("cmd /c cls");
switch (rightA){
case true : cout << "menu"; menu(field, newField); break;
case false : showQuizDialog(rightA); break;
default : cout << " ";
}
}while(rightA == false);
}
I'm a bit hintless. I may have some logic failure in it i just don't see at the moment.
Greetings
E: I don't wanted to bomb you guys with code. But here is it:
bool showQuizDialog(bool rightA){
Quiz* quiz = Quiz::getInstance();
quiz -> askQuestion(rightA);
return rightA;
}
And the full askQuestion:
bool Quiz::askQuestion(bool rightA) {
int fragenID = rand() % this->fragen.size(); //zufällige Fragen auswählen
struct Question frage = this->fragen.at(fragenID);
std::cout << frage.frage.c_str() << std::endl << endl; //Frage stellen
int rightanswer = this->listAnswers(frage.antworten);
int answer = this->readAnswer(0, frage.antworten.size() - 1);
if (answer == rightanswer){
rightA = true;
}
else {
rightA = false;
}
return rightA;
}
Is showQuizDialog(rightA) supposed to magically change the value of rightA? (I'm assuming you're not passing it by reference).
Did you mean to write rightA = showQuizDialog(rightA) or rightA = quiz -> askQuestion(rightA)?
Also, in your switch that switches on a bool, do you expect any other values than a true or a false?
Your showQuizDIalog is a call-by-value function. So always store the return value of the function into rightA, when calling showQuizDialog, that is :
rightA = showQuizDialog(rightA);
Otherwise, change your function declaration to allow pass-by-reference, maybe like this
showQuizDialog(&rightA);
and no need to return anything from the function(just use a pointer instead of a variable rightA inside the function)
Related
this is my first every time posting a question on stackoverflow so I apologize beforehand If my question seems messy. I have a class named token, and a derived class from it called function, integer, and operator. Token has a public variable of type int called _type. I assigned different _type values for each derived classes. The type for integer is 1, 2 for operator, and 3 for function. The purpose of this is so that I can implement different operations depending on the type encountered. I made an rpn function and in it I have something like this.
double RPN::rpn(){
Stack<Token*> rpn_stack;
while(input_q.empty() == false){
if(input_q.front()->_type == 1){
rpn_stack.push(input_q.pop());
}
if(input_q.front()->_type == 2){
double x = rpn_stack.pop()->value();
double y = rpn_stack.pop()->value();
//cout << x << y;
char i = input_q.pop()->op();
if(i == '*'){
double result;
result = x * y;
rpn_stack.push(new Integer(result));
}
}
if(input_q.front()->_type == 3){
input_q.pop();
rpn_stack.push(new Integer(_val));
}
}
return rpn_stack.top()->value();
}
after testing it a couple of times, I found out that the zsh:segmentation fault problem is caused by the input_q.pop() in
if(input_q.front()->_type == 3){
input_q.pop();
rpn_stack.push(new Integer(_val));
}
However, the code works if I change the order of the if statements like this
double RPN::rpn(){
Stack<Token*> rpn_stack;
while(input_q.empty() == false){
if(input_q.front()->_type == 3){
input_q.pop();
rpn_stack.push(new Integer(_val));
}
if(input_q.front()->_type == 1){
rpn_stack.push(input_q.pop());
}
if(input_q.front()->_type == 2){
double x = rpn_stack.pop()->value();
double y = rpn_stack.pop()->value();
//cout << x << y;
char i = input_q.pop()->op();
if(i == '*'){
double result;
result = x * y;
rpn_stack.push(new Integer(result));
}
}
}
return rpn_stack.top()->value();
}
which leads me to question whether the problem was input_q.pop() in the first place. It also works if I were to assign input_q.front()->_type to a static variable inside the while loop like this
double RPN::rpn(){
Stack<Token*> rpn_stack;
while(input_q.empty() == false){
int type = input_q.front()->_type;
if(type == 1){
rpn_stack.push(input_q.pop());
}
if(type == 2){
double x = rpn_stack.pop()->value();
double y = rpn_stack.pop()->value();
//cout << x << y;
char i = input_q.pop()->op();
if(i == '*'){
double result;
result = x * y;
rpn_stack.push(new Integer(result));
}
}
if(type == 3){
input_q.pop();
rpn_stack.push(new Integer(_val));
}
}
return rpn_stack.top()->value();
}
At this point I am very confused as to what is causing zsh:segmentation fault when using the first version. Im wondering if the problem lies in accessing input_q.front()->_type? I could just use the second and third version but I really want to know what is causing zsh:segmentation fault on the first version. If it helps, here is the simple program I wrote to test it. I am also using stack and queue if it helps.
Queue<Token *> postfix;
postfix.push(new Integer(3));
postfix.push(new Integer(5));
postfix.push(new Operator("*"));
RPN rpn(postfix);
cout << "3 5 *: " << rpn() << endl;
cout << "-------------" << endl;
Queue<Token *> postfix2;
postfix2.push(new Integer(3));
postfix2.push(new Function("X"));
postfix2.push(new Operator("*"));
rpn.set_input(postfix2);
cout << "3 x *: (x=3): " << rpn(3) << endl;
the rpn function is called using the () operator in the RPN class. the RPN class has a private variable called _val that is assigned a value to by the () operator. Hope the information Ive provided is enough. Thank you for your time, would appreciate the input!
With reference to your first code snippet, when you say this:
if(input_q.front()->_type == 1){
rpn_stack.push(input_q.pop());
}
if(input_q.front()->_type == 2){
...
You don't check if there's anything left on the input queue the second time you call input_q.front.
A simple fix is to insert a continue statement, like this:
if(input_q.front()->_type == 1){
rpn_stack.push(input_q.pop());
continue;
}
...
You will then loop back to the while statement which checks whether the queue is empty before proceeding.
There are other places in the code where you need to make a similar change, but you get the idea.
I was wondering what I may have done wrong in writing this simple function which is supposed to return true if the given number is a prime, or false if not a prime.
bool isPrime(int num)
{
if (num <= 1)
{
status = false;
}
else
{
for (int i = 1; i <= num; i++)
{
if (num % i == 0)
{
dividers++;
}
}
if (dividers == 2)
{
status = true;
}
else
{
status = false;
}
}
return status;
}
Obviously, my main looks like this:
bool isPrime(int num);
bool status;
int dividers = 0;
int main() {
isPrime(2);
if (!isPrime)
{
std::cout << "Not prime" << std::endl;
}
else
{
std::cout << "Prime" << std::endl;
}
return 0;
}
I'm a C++ beginner and I'd really appreciate it if someone could help me there and correct my logic.
Have a good day:)
The immediate problem is in this two lines:
isPrime(2);
if (!isPrime)
The first line calls the function and discards the returned value. The second line converts a pointer to the function to bool. The output of your code does not depend on what you actually do in isPrime.
That is not how you call a function and use its result!
Instead you want
if (isPrime(2)) {
or
bool isP = isPrime(2);
if (isP) { ...
As mentioned in comments, there are also problems in the implementation of isPrime, but I hope this is enough to set you back on the right track.
PS: You should get rid of the global variable status. You do not need both, the return value and a global that stores the result, and if you can choose, you should definitely go for the return value.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
So for my comp sci class I was tasked with adding, subtracting, dividing, and multiplying Roman Numerals if they pass 12 rules that I have been given.
I created a 13 element boolean array to keep track of which rules were broken. I created a function called checkErrors, which calls each of the 12 rule checking functions. I call the checkErrors to check each roman numeral before the calculation is done and print out which of the errors is wrong (if any) but instead of just printing out the ones that are wrong it prints each one.
Below is a snippet from checkErrors which is the same for each rule (checkErrorOne, checkErrorTwo...etc.). If the rule is broken, errors[0] is set to false to show that the whole roman numeral is not legal.
`bool checkErrors(string romanNumeral, bool * errors) {
if (checkErrorOne(romanNumeral) == false) {
errors[1] = false;
errors[0] = false;
}
if (checkErrorTwo(romanNumeral) == false) {
errors[2] = false;
errors[0] = false;
}
if (checkErrorThree(romanNumeral) == false) {
errors[3] = false;
errors[0] = false;
}
if (checkErrorFour(romanNumeral) == false) {
errors[4] = false;
errors[0] = false;
}
if (checkErrorFive(romanNumeral) == false) {
errors[5] = false;
errors[0] = false;
}
if (checkErrorSix(romanNumeral) == false) {
errors[6] = false;
errors[0] = false;
}
if (checkErrorSeven(romanNumeral) == false) {
errors[7] = false;
errors[0] = false;
}
if (checkErrorEight(romanNumeral) == false) {
errors[8] = false;
errors[0] = false;
}
if (checkErrorNine(romanNumeral) == false) {
errors[9] = false;
errors[0] = false;
}
if (checkErrorTen(romanNumeral) == false) {
errors[10] = false;
errors[0] = false;
}
if (checkErrorEleven(romanNumeral) == false) {
errors[11] = false;
errors[0] = false;
}
if (checkErrorTwelve(romanNumeral) == false) {
errors[12] = false;
errors[0] = false;
}
if (errors[0] == true)
return true;
else if (errors[0] == false)
return false;
}
`
to return the value of the first element to say if it is legal.
After this when I go to print each rule that was broken I use the following:
void printFunction(string romanNumeral1, string romanNumeral2, string mathOperator, bool errors[]){
if (checkErrors(romanNumeral1, errors) == false && checkErrors(romanNumeral2, errors) == true){
cout << romanNumeral1 << " is illegal becasue" << endl;
if (errors[1] == false)
cout << "Contains a letter that is not M, D, C, L, X, V, or I;" << endl;
if (errors[2] == false)
cout << "I is not followed by I, V, or X;" << endl;
if (errors[3] == false)
cout << "X is not followed by I, V, X, L, or C;" << endl;
for each of the 12 rules. It is printing out every one of the errors, not each one that is wrong.
If someone could help with my logic it would be greatly appreciated.
void printFunction(string romanNumeral1, string romanNumeral2, string mathOperator, bool errors[]){
if (checkErrors(romanNumeral1, errors) == false && checkErrors(romanNumeral2, errors) == true){
cout << romanNumeral1 << " is illegal becasue" << endl;
if (errors[1] == false)
cout << "Contains a letter that is not M, D, C, L, X, V, or I;" << endl;
if (errors[2] == false)
cout << "I is not followed by I, V, or X;" << endl;
if (errors[3] == false)
cout << "X is not followed by I, V, X, L, or C;" << endl;
Edit: Why does the code I wrote print out each of the 12 errors I created instead of only printing out the ones that were violated?
Thanks
Off-topic: Your program can be simplified by having an array of error messages.
The if statement ladder would be replaced by a loop:
for (unsigned int i = 0U; i < MAXIMUM_ERROR_TYPES; ++i)
{
if (errors[i])
{
std::cout << error_messages[i];
}
}
Since there is less code, there will be less possibility of injected defects.
Ok, first of all, you didn't post your checkErrors code, so i am assuming here.
I think that you defined is as
bool checkErrors(string, bool errors[13]){
which means, that it does not take a pointer, but a copy of the 13 booleans. So they get modified within your function, but not outside it. Change it to:
bool checkErrors(string, bool* errors){
ps. Next time, please think about how people with no knowledge about your poblem will understand it. Saves you a lot of flak ;)
Problem with returning booleans in c++..
bool find( const TrieNode &node, const string word )
{
if (word.length() == 0)
{
if (node.isWord)
{
cout << "TRUE" << endl;
return true;
}
else
{
cout << "FALSE" << endl;
return false;
}
}
char firstletter = word.at(0);
int index = firstletter - 'a';
if (node.letters[index] == NULL)
{
return false;
}
else
{
find (*node.letters[index],word.substr(1,(word.length() - 1)));
}
}
in my main I have
cout << find(*mynode,"word") << endl;
would yield to :
FALSE
95
clearly, a cout of FALSE means that the function returns false.. However, when I print out the result of the function, I get 95 which evaluates to true.. Any reason why it could be doing this?
thanks
Your missing a final return statement, so your getting whatever is in the low byte of EAX, which is random garbage. your probably want return true; at the very end of your function.
Your should pump the warning level of your compiler as it should be telling you this (something along the lines of "not all control paths return a value").
The problem is with your final if statement:
if (node.letters[index] == NULL) {
return false;
}
else {
//if execution gets here, the return value of the function is undefined
find (*node.letters[index],word.substr(1,(word.length() - 1)));
}
...perhaps try:
if (node.letters[index] == NULL) {
return false;
}
else {
return find (*node.letters[index],word.substr(1,(word.length() - 1)));
}
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.