C++ returning boolean as 95 - c++

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)));
}

Related

vector, removing object trouble

I am new to c++ and am currently learning sfml.
I have set up a system that adds one 'Snowpile' object to the vector. But when I keep hitting errors like "can't increment vector past iterator past end" or that it's outside the scope.
std::vector<Snowpile*> snowpiles;
I want it to check every snowpile for the removed2 bool, and delete the ones that do have it.
for (auto s_it = snowpiles.begin(); s_it != snowpiles.end(); s_it++) {
int sindex = std::distance(snowpiles.begin(), s_it);
if (snowpiles[sindex]->getSprite_S().getGlobalBounds().intersects(player.getSpriteP().getGlobalBounds()) && snowpiles[sindex]->melting == false) {
snowpiles[sindex]->melting = true;
}
else if (snowpiles[sindex]->getSprite_S().getGlobalBounds().intersects(player.getSpriteP().getGlobalBounds()) && snowpiles[sindex]->melting == true) {
snowpiles[sindex]->melting = true;
}
else if (!snowpiles[sindex]->getSprite_S().getGlobalBounds().intersects(player.getSpriteP().getGlobalBounds()) && snowpiles[sindex]->melting == true) {
snowpiles[sindex]->melting = false;
}
snowpiles[sindex]->meltedrem(sindex, snowpiles, m_win);
if (snowpiles[sindex]->removed2 == true)
{
cout << "Detected removed 2 at " << sindex << endl;
//delete snowpiles[sindex];
snowpiles.erase(snowpiles.begin() + sindex - 1);
}
}
The melting parts determine whether the player is on top of a snowpile. The meltdrem functions checks for bool 'melting' == true and then proceeds to start the timer. After a few seconds (+ animations) it sets the bool removed2 to true.
I know that at the program at least sees the bools changing, so thats not it.
Am I simply using vector wrong, or do I need to change something in my loop?
The loop is located in the while(window.isOpen()) loop in int main.
For starters it is unclear why there is used the expression
snowpiles.erase(snowpiles.begin() + sindex - 1);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
instead of
snowpiles.erase(snowpiles.begin() + sindex);
^^^^^^^^^^^^^^^^^^^^^^^^^^
if in a comment you wrote
//delete snowpiles[sindex];
You need to increase the iterator in the for loop only when a current object was not removed.
Change the loop the following way
for (auto s_it = snowpiles.begin(); s_it != snowpiles.end(); ) {
//...
if (snowpiles[sindex]->removed2 == true)
{
cout << "Detected removed 2 at " << sindex << endl;
//delete snowpiles[sindex];
s_it = snowpiles.erase( s_it );
}
else
{
++s_it;
}
}

What is the problem with this boolean function?

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.

Why does the removal of this return statement affect the outcome of the entire recursive function?

I am writing a palindrome checker using recursion.
I am confused to why removing the
return true
Statement at the end of the function affects the return value.
int firstChar = 0;
int lastChar = 0;
// These two variables are used to transverse the string from both ends
// eventually meeting
Code #1:
bool palindromeCheck (string text, int firstChar, int lastChar)
{
string tempCleanText = text;
// Removes all punctation and space
if (firstChar == 0)
{
// Cleans text, ignore.
tempCleanText = cleanString(tempCleanText);
// Sets this variable to the end of the string
lastChar = tempCleanText.size() - 1;
}
// Base Case
if (firstChar >= lastChar)
{
return true;
}
if (tempCleanText.at(firstChar) == tempCleanText.at(lastChar))
{
palindromeCheck(tempCleanText, ++firstChar, --lastChar);
}
else
{
return false;
}
return true; // Keeping this in works
}
This returns true, as it should for all palindromes, and false for all non-palindromes.
Code #2:
bool palindromeCheck (string text, int firstChar, int lastChar)
{
string tempCleanText = text;
// Removes all punctation and space.
if (firstChar == 0)
{
// Cleans text, ignore.
tempCleanText = cleanString(tempCleanText);
// Sets this variable to the end of the string
lastChar = tempCleanText.size() - 1;
}
// Base Case
if (firstChar >= lastChar)
{
return true;
}
if (tempCleanText.at(firstChar) == tempCleanText.at(lastChar))
{
palindromeCheck(tempCleanText, ++firstChar, --lastChar);
}
else
{
return false;
}
// there is no return true here, and so the output is no longer correct
}
This returns true, for only some of the palindromes, and false for all non-palindromes.
Palindromes, such as,
amanaplanacanalpanama <- size length 21
Returns false, when it should return true.
Through testing, it is shown that the base case is entered using the last palindrome, meaning that the function sees it as a valid palindrome. But, I'm assuming the program then unwinds the call stack and as it goes through all the previous function calls, something makes the function return false.
For starters the function is in any case incorrect. For example for the string "1231" the function returns true. I hope you can check this yourself.
This part of the function
if (tempCleanText.at(firstChar) == tempCleanText.at(lastChar))
{
palindromeCheck(tempCleanText, ++firstChar, --lastChar);
}
else
{
return false;
}
return true; // Keeping this in works
should be at least substituted for the following code snippet
if (tempCleanText.at(firstChar) == tempCleanText.at(lastChar))
{
return palindromeCheck(tempCleanText, ++firstChar, --lastChar);
}
else
{
return false;
}
That is this return statement
return true; // Keeping this in works
shall be entirely removed.
As for your question then without the last return statement the function have undefined behavior because it returns nothing after the if statement. That is the if statement
if (tempCleanText.at(firstChar) == tempCleanText.at(lastChar))
{
palindromeCheck(tempCleanText, ++firstChar, --lastChar);
}
else
{
return false;
}
successfully was executed provided that
tempCleanText.at(firstChar) == tempCleanText.at(lastChar))
and what does the function return after executing the sub-statement of the if statement? Nothing! :)
Also it does not make sense to declare two additional parameters (indices) apart from the string itself because in any case the string is passed by value and you always can get its size by calling the member function size().
I can suggest the following implementation of the function Similarly to your function this function implementation returns true in case when an empty string is passed.
#include <iostream>
#include <iomanip>
#include <string>
#include <cctype>
bool palindromeCheck( std::string s )
{
if ( s.size() < 2 )
{
return true;
}
else if ( ispunct( ( unsigned char )s.front() ) || isspace( ( unsigned char )s.front() ) )
{
return palindromeCheck( s.substr( 1 ) );
}
else if ( ispunct( ( unsigned char )s.back() ) || isspace( ( unsigned char )s.back() ) )
{
return palindromeCheck( s.substr( 0, s.size() - 1 ) );
}
else if ( s.front() == s.back() )
{
return s.size() == 2 ? true : palindromeCheck( s.substr( 1, s.size() - 2) );
}
else
{
return false;
}
}
int main()
{
std::cout << std::boolalpha << palindromeCheck( "" ) << '\n';
std::cout << std::boolalpha << palindromeCheck( "1" ) << '\n';
std::cout << std::boolalpha << palindromeCheck( "1 1" ) << '\n';
std::cout << std::boolalpha << palindromeCheck( "1,2,2,1" ) << '\n';
std::cout << std::boolalpha << palindromeCheck( "1 2 3 2 1" ) << '\n';
std::cout << std::boolalpha << palindromeCheck( "12341" ) << '\n';
return 0;
}
The program output is
true
true
true
true
true
false
may be
// ...
if (tempCleanText.at(firstChar) == tempCleanText.at(lastChar))
{
return palindromeCheck(tempCleanText, ++firstChar, --lastChar);
}
else
return false;
// ...
Returning from a non-void function without explicitly returning a value via the return keyword invokes undefined behavior. Per the C++ spec, a program that invokes undefined behavior is free to do literally anything at all, and all blame for any resulting weirdness will be placed at the feet of the programmer that wrote the code that invoked the undefined behavior.
What's likely actually happening in this case is that when your function returns by dropping off the end of the function (and doesn't do a return false), the location where the function's return-value was stored simply never gets written to -- which means that, as far as the calling code is concerned, the value returned by your function will be equal to whatever value happened to be present at that location when your function returns. The pre-existing value at that location will be arbitrary and hard-to-predict, since it is a result of various details regarding how the program executes, and therefore the behavior of the program will be arbitrary and hard-to-predict as well.
The solution is to be sure to always explicitly return a value; enabling warnings in your compiler will allow it to help you in that task by warning you if you ever forget to return a value in some code-path.

Checking Errors of Roman Numerals Given A Set of Rules [closed]

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 ;)

C++ returning bool is always false?

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)