Testing if a number is a Palindrome using different functions (C++) - c++

The code I am using is:
#include <iostream>
using namespace std;
int reverse (int number){
int t = number, m = 0;
do
{
m = m*10 + t%10;
} while(t /= 10);
return m == number;
}
bool isPalindrom(int number){
bool Palindrom = reverse(number);
if(Palindrom == true){
return true;
} else {
return false;
}
return 0;
}
int main()
{
int number;
cout << "Please input a number " << endl;
cin >> number;
if(isPalindrom){
cout << "This is a Palindrom" << endl;
} else {
cout << "This is not a Palindrom" << endl;
}
}
The issue I am having is that isPalindrom is always evaluating to true. I believe it is because I am trying to set this up incorrectly. The program asks us to use the two functions bool isPalindrom(int number) and int reverse(int number). I'm just learning to use functions in C++ so i'm not to sure what I should do. Should I have reverse return the numbers flipped self (m) then in palindrom compare number to m and if it evaluates to true, it will return true. Then in the main check with an if statement to see if isPalindrom is true/false.

You are not calling the function correctly.
if(isPalindrom){
cout << "This is a Palindrom" << endl;
} else {
cout << "This is not a Palindrom" << endl;
}
To call it you have to supply a parameter like this
if (isPalindrom(number)) {
....
In your code isPlanindrom is (I believe, but actually it does not matter if I am right on this point) a function pointer and because it is in the condition of if it gets converted to a bool, which is true always.
PS: I just noticed that I was too fast in writing the answer. I just saw this one problem and didnt look at the rest of the code. It seems like you need to learn about very basics which would be too much to cover here in an answer. My suggestion: Get a book and rtfm :P

In main, you are evaluating the existence of a function called isPalindrom; you aren't actually calling the function. if(isPalindrom){ should become if(isPalindrom(number)){.

You forget to call isPalindrom with an argument. Here's the fix:
#include <iostream>
using namespace std;
bool reverse (int number){
int t = number, m = 0;
do
{
m = m*10 + t%10;
} while(t /= 10);
return m == number;
}
bool isPalindrom(int number){
return reverse(number);
}
int main()
{
int number;
cout << "Please input a number " << endl;
cin >> number;
if(isPalindrom(number)){
cout << "This is a Palindrom" << endl;
} else {
cout << "This is not a Palindrom" << endl;
}
}
I've also:
simplified your isPalindrom() function to a simple return statement;
set the return of reverse from int to bool.
You can try a LiveDemo

Short answer: you forgot to call isPalindrom.
Long answer: isPalindom decays to a nonnull function pointer, and nonnull pointers test true, this you always see the the if branch taken.
Also:
Yes, judging both by the name and the return type, reverse is intended to return the reverse of a number.
And correspondingly, it is the job of isPalindom to do the actual comparisons.
Furthermore, in most cases,
if (boolean) { return true; }
else { return false; }
should be replaced with
return boolean;
Finally, you really ought to be testing whether or not cin succeeded and your input is valid. (e.g. is the user allowed to enter 0? -73? Zero?)

Related

Why is my C++ function skipping my IF statements?

So, let me preface that I am still learning C++ and would appreciate some guidance on what I am doing wrong.
My prompt is to write a function that continuously prompts a user for a valid age (between 0 and
100) and the function must only return the age to the caller of the function after a valid age is retrieved. AND For each function, you must declare the function using a function prototype before main and then define the function after main.
Here is my code,
#include <iostream>
using namespace std;
int num;
bool valid;
int validateInput()
{
cout << "Pick a number between 0 and 100" << endl;
cin >> num;
while(bool valid = false)
{
if(num <= 0)
{
cout << "Error: Number is invalid because it's too low" << endl;
bool valid = false;
return 0;
}
else if (num >= 100)
{
cout << "Error: Number is invalid because it's too high" << endl;
bool valid = false;
return 0;
}
else
{
cout << "You are " << num << " years old." << endl;
bool valid = true;
return 0;
}
}
}
int main()
{
validateInput();
return 0;
}
So I am trying to get my program to work but the IF statements keep getting skipped.
Am I misunderstanding something? Any and all help is very much appreciated.
EDIT: Thank you to Arvin and iammilind for your help.
I was able to fix the code so my while loop condition would actually trigger, moved my cout statements into the loop and so I wouldn't get infinite output.
My final working code looked like this.
#include <iostream>
using namespace std;
int num;
bool valid = false;
int validateInput()
{
while(!valid)
{
cout << "Pick a number between 0 and 100" << endl;
cin >> num;
if(num <= 0)
{
cout << "Error: Number is invalid because it's too low" << endl << endl;
bool valid = false;
}
else if (num >= 100)
{
cout << "Error: Number is invalid because it's too high" << endl << endl;
bool valid = false;
}
else
{
cout << "You are " << num << " years old." << endl;
bool valid = true;
return 0;
}
}
}
int main()
{
validateInput();
return 0;
}
You give a false value to the while loop that makes the while loop doesn't start the loop.
do this instead:
bool valid = false;
while (!valid){ // while valid is still false, do the loop
// your code here
}
Further explanation: You're currently using sentinel-controller loop
reference: https://simplecplusplus.wordpress.com/tag/sentinel-controlled-loop/
In order for while loop to start running, you've to provide the "true" condition to the while, and it will start looping until the condition turn out to false.
Programming tips for you: next time, you've to see the larger picture of your code every time you're trying to debugging. If you're sure the if-else code is running and have no problem, you have to enlarge your investigation for the bug, maybe it's the while loop that didn't work, not if-else. And if the while loop seems having no problem, maybe its the function or the caller of the function
while(bool valid = false) never allows the execution to enter the loop. Hence the if conditions are never called.
Use it as below:
while(valid == false) { // see '==' sign. `while(not valid)` is also fine
// ... your 'if' conditions
}
Actually you are creating a locally scope variable within while() by having a bool before it. So bool valid hides bool ::valid (declared outside).
Also, once the loop ends, you may want to reset it to false again. Otherwise this function will never be able to used again!
Using globals (bool valid) for such functionality is a bad design.

C++ program stuck in an infinite loop

Please note that I am a complete beginner at C++. I'm trying to write a simple program for an ATM and I have to account for all errors. User may use only integers for input so I need to check if input value is indeed an integer, and my program (this one is shortened) works for the most part.
The problem arises when I try to input a string value instead of an integer while choosing an operation. It works with invalid value integers, but with strings it creates an infinite loop until it eventually stops (unless I add system("cls"), then it doesn't even stop), when it should output the same result as it does for invalid integers:
Invalid choice of operation.
Please select an operation:
1 - Balance inquiry
7 - Return card
Enter your choice and press return:
Here is my code:
#include <iostream>
#include <string>
using namespace std;
bool isNumber(string s) //function to determine if input value is int
{
for (int i = 0; i < s.length(); i++)
if (isdigit(s[i]) == false)
return false;
return true;
}
int ReturnCard() //function to determine whether to continue running or end program
{
string rtrn;
cout << "\nDo you wish to continue? \n1 - Yes \n2 - No, return card" << endl;
cin >> rtrn;
if (rtrn == "1" and isNumber(rtrn)) { return false; }
else if (rtrn == "2" and isNumber(rtrn)) { return true; }
else {cout << "Invalid choice." << endl; ReturnCard(); };
return 0;
}
int menu() //function for operation choice and execution
{
int choice;
do
{
cout << "\nPlease select an operation:\n" << endl
<< " 1 - Balance inquiry\n"
<< " 7 - Return card\n"
<< "\nEnter your choice and press return: ";
int balance = 512;
cin >> choice;
if (choice == 1 and isNumber(to_string(choice))) { cout << "Your balance is $" << balance; "\n\n"; }
else if (choice == 7 and isNumber(to_string(choice))) { cout << "Please wait...\nHave a good day." << endl; return 0; }
else { cout << "Invalid choice of operation."; menu(); }
} while (ReturnCard()==false);
cout << "Please wait...\nHave a good day." << endl;
return 0;
}
int main()
{
string choice;
cout << "Insert debit card to get started." << endl;
menu();
return 0;
}
I've tried every possible solution I know, but nothing seems to work.
***There is a different bug, which is that when I get to the "Do you wish to continue?" part and input any invalid value and follow it up with 2 (which is supposed to end the program) after it asks again, it outputs the result for 1 (continue running - menu etc.). I have already emailed my teacher about this and this is not my main question, but I would appreciate any help.
Thank you!
There are a few things mixed up in your code. Always try to compile your code with maximum warnings turned on, e.g., for GCC add at least the -Wall flag.
Then your compiler would warn you of some of the mistakes you made.
First, it seems like you are confusing string choice and int choice. Two different variables in different scopes. The string one is unused and completely redundant. You can delete it and nothing will change.
In menu, you say cin >> choice;, where choice is of type int. The stream operator >> works like this: It will try to read as many characters as it can, such that the characters match the requested type. So this will only read ints.
Then you convert your valid int into a string and call isNumber() - which will alway return true.
So if you wish to read any line of text and handle it, you can use getline():
string inp;
std::getline(std::cin, inp);
if (!isNumber(inp)) {
std::cout << "ERROR\n";
return 1;
}
int choice = std::stoi(inp); // May throw an exception if invalid range
See stoi
Your isNumber() implementation could look like this:
#include <algorithm>
bool is_number(const string &inp) {
return std::all_of(inp.cbegin(), inp.cend(),
[](unsigned char c){ return std::isdigit(c); });
}
If you are into that functional style, like I am ;)
EDIT:
Btw., another bug which the compiler warns about: cout << "Your balance is $" << balance; "\n\n"; - the newlines are separated by ;, so it's a new statement and this does nothing. You probably wanted the << operator instead.
Recursive call bug:
In { cout << "Invalid choice of operation."; menu(); } and same for ReturnCard(), the function calls itself (recursion).
This is not at all what you want! This will start the function over, but once that call has ended, you continue where that call happened.
What you want in menu() is to start the loop over. You can do that with the continue keyword.
You want the same for ReturnCard(). But you need a loop there.
And now, that I read that code, you don't even need to convert the input to an integer. All you do is compare it. So you can simply do:
string inp;
std::getline(std::cin, inp);
if (inp == "1" || inp == "2") {
// good
} else {
// Invalid
}
Unless that is part of your task.
It is always good to save console input in a string variable instead of another
type, e.g. int or double. This avoids trouble with input errors, e.g. if
characters instead of numbers are given by the program user. Afterwards the
string variable could by analyzed for further actions.
Therefore I changed the type of choice from int to string and adopted the
downstream code to it.
Please try the following program and consider my adaptations which are
written as comments starting with tag //CKE:. Thanks.
#include <iostream>
#include <string>
using namespace std;
bool isNumber(const string& s) //function to determine if input value is int
{
for (size_t i = 0; i < s.length(); i++) //CKE: keep same variable type, e.g. unsigned
if (isdigit(s[i]) == false)
return false;
return true;
}
bool ReturnCard() //function to determine whether to continue running or end program
{
string rtrn;
cout << "\nDo you wish to continue? \n1 - Yes \n2 - No, return card" << endl;
cin >> rtrn;
if (rtrn == "1" and isNumber(rtrn)) { return false; }
if (rtrn == "2" and isNumber(rtrn)) { return true; } //CKE: remove redundant else
cout << "Invalid choice." << endl; ReturnCard(); //CKE: remove redundant else + semicolon
return false;
}
int menu() //function for operation choice and execution
{
string choice; //CKE: change variable type here from int to string
do
{
cout << "\nPlease select an operation:\n" << endl
<< " 1 - Balance inquiry\n"
<< " 7 - Return card\n"
<< "\nEnter your choice and press return: ";
int balance = 512;
cin >> choice;
if (choice == "1" and isNumber(choice)) { cout << "Your balance is $" << balance << "\n\n"; } //CKE: semicolon replaced by output stream operator
else if (choice == "7" and isNumber(choice)) { cout << "Please wait...\nHave a good day." << endl; return 0; }
else { cout << "Invalid choice of operation."; } //CKE: remove recursion here as it isn't required
} while (!ReturnCard()); //CKE: negate result of ReturnCard function
cout << "Please wait...\nHave a good day." << endl;
return 0;
}
int main()
{
string choice;
cout << "Insert debit card to get started." << endl;
menu();
return 0;
}

A member test using Recursion

I was having trouble understanding recursion. I'm looking for some feedback here to see how this program looks.
Question :::
Write a recursive Boolean function named isMember. The function should accept three parameters: an array of integers, an integer indicating the number of elements in the array, and an integer value to be searched for. The function should return true if the value is found in the array or false if the value is not found. Demonstrate the use of the function in a program that asks the user to enter an array of numbers and a value to be searched for.
What I have::
#include <iostream>
using namespace std;
bool isMember(int[],int,int);
int main()
{
const int SIZE = 10;
int numSearch;
int elementz[SIZE];
for(int i = 0; i < SIZE; i++)
{
cout << "Element " << i + 1 << "\t";
cin >> elementz[i];
}
cout << "Enter element to search\n";
cin >> numSearch;
bool value = isMember(elementz,SIZE,numSearch);
if(value ==1)
cout << "Element is found\n";
else
cout << "Element not found\n";
return 0;
}
bool isMember(int arr[], int sizze, int num)
{
if(arr[sizze] == num)
return true;
else
isMember(arr,sizze -1, num);
}
Your function doesn't return if the if clause is false. Also, keep in mind that indexes start at 0, not 1 (and why sizze?).
I would recommend starting with an array of 3 values, rather than of 10. That way you''ll be able to manually follow and unfold the successive calls.
In order for recursions to work, you need not only a "conditional stop", but an inconditional stop too.
In your example, you only provided a conditional stop. To make it work correctly, try something like this:
bool isMember(int arr[], int sizze, int num)
{
if ( sizze < 0 ) // "inconditional stop"
return false;
if(arr[sizze] == num) // conditional stop. It could happen or not
return true;
else
isMember(arr,sizze -1, num);
}

C++ cout won't work inside for and if?

I have those two pieces of code as my home assignment. The code looks all fine to me, but it won't print out what I want, no matter what. In fact, the console output remains completely empty.
The first program is supposed to print out all numbers that fulfil the ladna() function requirements and are between 1 and a:
#include <iostream>
using namespace std;
int a;
int i = 1;
bool ladna(int a)
{
if((((a>>4)*5+a*2)%3)==1)
return true;
else
return false;
}
int main()
{
cerr << "Podaj liczbe: " << endl;
cin >> a;
while (i <= a){
if (ladna(a)){
cout << i << " ";
}
i++;
}
}
the ladna() function is premade and I have to use it as is.
I tried changing while into do...while and for, didn't help. Doesn;t work with cerr either.
The second code has to print out all the natural divisors of number a.
#include <iostream>
using namespace std;
int main()
{
int a;
cerr << "Podaj liczbe" << endl;
cin >> a;
for (int i = 0; i >= a; i++){
if (a % i == 0){
cout << i << endl;
}
}
return 0;
}
Doesn't work either.
To me it looks like both pieces of code have the same issue, because they are written in the same way, based on the same principle, and the error is the same. Hence my assumption, that the cause is the same as well.
Unfortunately, for the love of me, I simply can't see what said error is...
For the first code:
I think you should call ladna function with i, like ladna(i)
For the second code:
In for it should be i<=a
'%' is the modulo operator, during the execution of (a%i) you divide a with i and take the remainder, since i start with zero you will get "Floating point exception (core dumped)" due to division by zero. So, for should start with 1. This should work:
for (int i = 1; i <= a; i++){
if (a%i == 0){
cout << i << endl;
}
}

I'm having difficulty with my do while loop. It only executes once

The battleship program I wrote is supposed to loop a infinite amount of times until a condition is met. However it stops after the first execution. What is the matter with my loop? The code runs, however towards the end it outputs game over twice when its not supposed to. There are still more ships remaining in the game.
#include<iostream>
#include<fstream>
#include<string>
#include<cmath>
using namespace std;
bool FleetSunk();
void Fire(int&, int&, char&);
char ocean[25][25];
int main()
{
int x;
int y;
char spot;
ifstream input;
input.open("ocean.txt");
for(x=0;x<25;x++)
{
for(y=0;y<25;y++)
{
input >> ocean[x][y];
}
}
FleetSunk == false;
do
{
cout << "Please input x coordinate: ";
cin >> x;
cout << endl << "Please input y coordinate: ";
cin >> y;
cout<< endl;
Fire(x,y,spot);
FleetSunk();
}while(FleetSunk() == false);
}
void Fire(int& x, int&y, char&spot)
{
spot = ocean[x][y];
if(spot == '#')
{
cout << "You Have hit a ship"<< endl;
ocean[x][y] = 'H';
}
else if(spot == 'H')
{
cout << "HIT AGAIN" << endl;
}
else if(spot == '-')
{
cout << "MISS" << endl;
}
}
bool FleetSunk()
{
int m;
int n;
for(m=0;m < 25; m++)
{
for(n=0;n<25;n++)
{
if(ocean[m][n] == '#')
{
cout << "You still have ships remaining" << endl;
}
else
{
cout<< "You have hit all the ships. GAME OVER!" << endl;
return true;
}
}
}
}
Your FleetSunk function has two problems. One should have been a compiler warning, and one is a logical problem.
Firstly, not all paths in the function return a value... Technically. Although in your case that's not quite true because of the logic problem. Let me be more specific: If your entire board is populated with '#', and no shots are taken, then the function behaviour is undefined. It completes the loop and then does not return a value.
So now let's do the logic. You cannot know whether there are any un-hit ship locations until you have examined the entire board. That means you cannot exit from your inner loop in the way you are doing. How about instead you return false if you encounter an "alive" position, and return true at the end of the function (which is only reached if you never encounter an "alive" position).
bool FleetSunk()
{
for( int m = 0; m < 25; m++ )
{
for( int n = 0; n < 25; n++ )
{
if( ocean[m][n] == '#' ) return false;
}
}
return true;
}
See in the comments under your question for other suggestions related to how you are calling FleetSunk in your loop. I also recommend (as evident in my code example) that you don't write stuff to cout in a function that is testing for some condition. It's the responsibility of the caller to do that, not the function itself.
Finally, I would just like to say that the line FleetSunk == false; above your loop really does not do what you might think. That will take the function pointer, convert it to boolean and compare it with false. It's a crazy thing to do, and also useless because the resulting value isn't used for anything. Just delete that line.