Recognize "010" and similar numbers as a palindrome using modulus in C++ - c++

First post! This is my second semester with "Advanced C & C++" so any help is GREATLY appreciated. I've already scoured as much of stackoverflow and a few other resources to try and help me understand what I'm doing (or not doing) with this slew of logically inept code.
The goal of this program is to recognize whether or not a 'number' given by the user is a palindrome. Sounds simple enough right?! Ugh...well this is what I have been stuck on:
#include <iostream>
using std::cout;
using std::cin;
#include <string>
using std::string;
#include <cstdlib>
int main()
{
//variable declarations
string buffer;
//user input
cout << "Enter a number to see if it is a palindrome[Q to quit]: ";
getline(cin, buffer);
//looooop
while(buffer != "Q" && buffer !="q")
{
int userNum, length, sum = 0, temp;
userNum = atoi(buffer.c_str());
for(temp = userNum; userNum !=0; userNum=userNum/10)
{
length = userNum % 10;
sum = sum*10+length;
}
if(temp==sum)
cout << temp << " is a palindrome!!\n\n";
else
cout << buffer << " is NOT a palindrome!\n\n";
cout << "Enter a number to see if it is a palindrome[Q to quit]: ";
getline(cin, buffer);
}
}
The problem arises when input of "010", or "400" is given. "400" is essentially "00400" in this case and both should be seen as a palindrome.

A better approach would be to get trailing zeros for the given number as below:
int noOfTrailingZeros = str.length;
while(str[--noOfTrailingZeros]=='0');
noOfTrailingZeros = str.length - noOfTrailingZeros;
Or the integer way as:
int noOfTrailingZeros = str.length;
while(num%10==0)
{
noOfTrailingZeros++;
num/=10;
}
Now, check for the input string whether it has the same number of zeros befire the number or not as:
int counterZeros = 0;
while(str[counterZeros++]=='0');
check these 2 numbers and if trailing zeros are more than the zeros at beginning, add that many at the beginning and pass that string to palindrome function.

First of all, to recognize a palindrome, you don't have to do atoi. Just pass from the start to the middle checking if
buffer[i] == buffer[length - i]
Second, use the atoi to make sure it is a number and you're done.
Other way is to compare the string with itself reversed:
string input;
cout << "Please enter a string: ";
cin >> input;
if (input == string(input.rbegin(), input.rend())) {
cout << input << " is a palindrome";
}

Related

Why the code does not loop when user enter incorrect lowercase letter

I am writing a code that generates a random number then assign the number to a letter in string letters then user has to guess the letter.
I am trying to loop the the question "Enter one lowercase letter: " if the user enters a letter that does not match randomLetter, but at the same time I have to make sure the letter is all in lower case (something we haven't learned in class but after searching I found a solution, hopefully it's the right way to go about it).
This while loop ends if user enters the incorrect lower letter. It does work when the letterGuess matches randomLetter.
The other thing I have to do is if user enters an incorrect lower letter then it needs to give feedback that the correct letter comes before or after the entered letter.
#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>
#include <algorithm>
using namespace std;
//function prototype
void displayNumber(int);
int main()
{
string letters = "abcdefghijklmnopqrstuvwxyz";
string randomLetter;
string letterGuess = "";
string wordLocation = " ";
int randomNumber = 0;
//display random number then assign a random number to letter string
displayNumber(randomNumber);
randomLetter = letters[randomNumber];
while (letterGuess.length() != 1) {
//ask user to enter a lowercase letter and determine if it matches the random letter
cout << "Enter one lowercase letter: ";
getline(cin, letterGuess);
if (all_of(letterGuess.begin(), letterGuess.end(), &::isupper)) {
cout << "letter must be lowercase.";
}
else if (randomLetter.find(letterGuess, 0) == -1) {
cout << "\nYou guessed the correct letter.";
}
else {
wordLocation.insert(0, letters);
} //end if
} //end while
return 0;
} //end of main function
void displayNumber(int num)
{
srand(time(0));
num = (rand() % 26) + 1;
cout << num << endl
<< endl;
} // end of displayNumber function
The specific problems you highlighted is caused by the looping condition,
while(letterGuess.length() != 1)
here when the user in the first iteration enters just one letter, the letterGuess string will have size = 1, and hence will cause breaking of loop.
Another problem is the fact that randomNumber remains 0, for it not to remain zero the displayNumber function must take a reference or return a value.
EDIT
To update randomNumber, modify the display function to :
int displayNumber()
{
srand(time(0));
int num = (rand() % 26) + 1;
cout << num << endl
<< endl;
return num;
}
and in the main:
randomNumber = displayNumber();
or alternatively
void displayNumber(int& num)
{
srand(time(0));
num = (rand() % 26) + 1;
cout << num << endl
<< endl;
}
and in the main:
displayNumber(randomNumber);
maybe rename it to generateRandom() which seems more accurate?
You your problem might be is here:
while (letterGuess.length() != 1)
because you when you enter one character you break the loop. To fix this you might go different routes, but easiest one is to check if letter is lower or upper.
while (letterGuess.length() != 1 || std::islower(letterGuess[0]))
Also now that I look at it closer, did you want to check if any characters in string are upper or all of them are upper?
all_of(letterGuess.begin(), letterGuess.end(), &::isupper)
would check if all characters are lower, but to check if only one character is upper use any_of()
any_of(letterGuess.begin(), letterGuess.end(), &::isupper)
Here is my little example code:
#include <iostream>
#include <algorithm>
using namespace std;
int main (void) {
std::string s = "Hello";
if (any_of(s.begin(), s.end(), &::isupper))
std::cout << "One is upper\n\n";
if (all_of(s.begin(), s.end(), &::isupper))
std::cout << "All are upper\n";
else
std::cout << "some might be upper\n";
return 0;
}
Output
EXECUTING ==================================================
One is upper
some might be upper
DONE ==================================================
Since you are newbie, another thing that I just noticed that I still remember from my newbie days. call srand(time(0)); once. Maybe at the begging of main(). Way you have it does produces the same random number every time. Read this

Printing words vertically

So I'm just starting in C++, so I'm not familiar with the language, though I do have knowledge of C. I'm trying to print words vertically. Here is the problem given.
Create an array of 25 strings.
Use a sentinel loop that reads from cin until the array is full or the end of input is reached
(when the user presses Ctrl-D), whichever comes first.
After the sentinel loop is over, use a for loop to move through the array.
Remember not to travel farther than the last array element that was input.
Print one array element (one string) followed by a newline
Use a for loop to move through the characters of the string you just printed
print one character followed by a newline
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
int main()
{
char word;
int count = 0;
cout << "Enter a word: (press Ctrl-D to quit)";
cin >> word;
int array1[25];
while (!cin.eof())
{
count = count + 1;
cout << "Enter a word: (press Ctrl-D to quit)";
cin >> word;
} //end while
for (word = 0; word <= array1[count]; word++)
{
cout << 'end1' << 'end1' << "There were " << count << "Words Entered" << 'end1';
}
} //end main
Code is rough, it compiles, but when it is in an infinite loop with numbers comes out after the texts.
Just for the hell of it
#include <iostream>
#include <string>
#include <iomanip>
#include <vector>
using namespace std;
int main() {
string word;
int count = 0;
vector<string> arrayOfStrings;
cout << "Enter a word: (press Ctrl-D to quit)";
while(cin >> word){
if(count < 25){
arrayOfStrings.push_back(word);
count = count + 1;
cout << "Enter a word: (press Ctrl-D to quit)";
} else {
cout << "25 strings was entered";
break;
}
}//end while
for ( int j = 0; j < arrayOfStrings.size(); j++ ){
cout << '\n' << '\n' << $j << "-st string entered " << arrayOfStrings[j] << '\n';
}
}//end main
This code reads exactly 25 strings, remembers them, and even outputs them later.
This is just an educational example, which basically ignores memory managment
I strongly suggest not to use this in any actual code.
It took me about 5 mins to write this.
There are a few errors in this code - perhaps if you are familiar with C, then quickly write a version in C and translate it to a more modern "C++ like" version. Perhaps look into std::string and std::vector to make life even easier.
int array1[25]; needs to store strings, therefore it is of the wrong type.
The while (!cin.eof()) loop needs to also check that it doesn't go over the bounds of the above array (i.e. at most 25 words).
The for (word = 0; word <= array1[count]; word++) loop that needs to loop exactly n times, where n is the number of words inputted, i.e. in the above while loop.

Trouble with strings and arrays

My goal is to make a program that inputs a phone number and outputs it in a standard format. It skips over any non-number characters, will output if there are not enough digits, and will also skip over any digits after the first ten digits. My raptor worked without a hitch, but it's been difficult to translate it to C++.
I am using Microsoft Visual Studio.
The problem is it is not running. If I put in anything more then one number in, I receive a fail error.
I am having some difficulty running this code.
Any and all help and advice would be greatly appreciated.
#include <iostream>
#include <string>
using namespace std;
void format(char outArray[], string inNumber)
{
outArray[0] = '(';
outArray[4] = ')';
outArray[5] = ' ';
outArray[9] = '-';
outArray[1] = inNumber[0];
outArray[2] = inNumber[1];
outArray[3] = inNumber[2];
outArray[6] = inNumber[3];
outArray[7] = inNumber[4];
outArray[8] = inNumber[5];
outArray[10] = inNumber[6];
outArray[11] = inNumber[7];
outArray[12] = inNumber[8];
outArray[13] = inNumber[9];
}
int main()
{
string phone, inNumber;
cout << "Please enter a phone number: ";
cin >> phone;
int index = 0;
int num = 0;
char outArray[14];
for (index; phone[index] >= '0' && phone[index] <= '9'; index++)
{
inNumber[num] = phone[index];
num++;
}
if (inNumber.size() > 10)
{
format(outArray, inNumber);
cout << "The properly formatted number is: ";
cout << outArray;
}
else {
cout << "Input must contain at least 10 digits." << endl;
}
system("pause");
return 0;
}
A few things to note:
Use std::string instead array of char array.
You do not need to check charters using a for loop unless you are not sure about the input(phone). However, if that's the case, use std::getline() to get the input and parse as follows using a range-based for loop.
You can use std::isdigit to check the character is a digit.
My goal is to make a program that inputs a phone number and outputs it
in a standard format. It skips over any non-number characters, will
output if there are not enough digits, and will also skip over any
digits after the first ten digits.
That means the number should have a minimum length of 10. Then the
if statement should be if (inNumber.size() >= 10)
Need a pass by ref call in the function format(), since you want to change the content of outArray. Additionally, inNumber could be a
const ref, since we do not change this string.
Updated code: (See a sample code online)
#include <iostream>
#include <string>
#include <cstddef> // std::isdigit, std::size_t
void format(std::string& outArray, const std::string& inNumber) /* noexcept */
{
for (std::size_t index = 0; index < 10; ++index)
{
if (index == 0) outArray += '(';
else if (index == 3) outArray += ") ";
else if (index == 6) outArray += '-';
outArray += inNumber[index];
}
}
int main()
{
std::string phone;
std::cout << "Please enter a phone number: ";
std::getline(std::cin, phone);
std::string inNumber;
for (char letter : phone)
if (std::isdigit(static_cast<unsigned char>(letter))) // check the letter == digits
inNumber += letter;
if (inNumber.size() >= 10)
{
std::string outArray;
format(outArray, inNumber);
std::cout << "The properly formatted number is: ";
std::cout << outArray;
}
else {
std::cout << "Input must contain at least 10 digits." << std::endl;
}
return 0;
}
inNumber[num] = phone[index]; //undefined behavior.
You cannot subscript inNumber now, since its capacity is 0, thus it can not store or access any element here.
You may need to use string's constructor whose parameter has a size_t type or string::reserve or string::resize.
And I'm happy to see cppreference get more complete now, learn to use it: http://en.cppreference.com/w/cpp/string/basic_string
BTW, this function won't do anything you want to:
void format(char outArray[], string inNumber)
maybe you'd like to have an signature like this?
void format(char outArray[], string& inNumber)

Permutation Issue

So I have a program here that is supposed to print to the screen permutations of a user input word that can be 4 to 10 characters long and there are supposed to be as many permutations as there are letters in the word. I almost have complete success, but there is one issue. When it prints the permutations, after the first about 2 permutations, it starts to not use all the letters and/or the same letter twice.
For example, if the user input word is "bill", the output is as follows:
llib illb ibll lbii
The fourth is is obviously not correct. The problem is more apparent with words that have more letters. I need it to only use the letters it has once. How do I go about fixing this in my code? Here is my code.
int main(void)
{
string word;
string randword;
string reverse;
int length;
int i = 0;
int j = 0;
string randCH;
cout << "Enter any word 4 to 10 letters in length: ";
cin >> word;
//Checks if word is less than 4 or greater than 10
while (1)
{
/*The code here is in the final program and I know it works. The problem is not here*/
}
length = word.length();
//Uses reverse function
reverse = reverseit(word);
/*reverseit is a function outside of main that makes the word backwards*/
//Prints all permutations
cout << endl << reverse << " ";
for (i = 0; i < word.length() - 1; i++)
{
for (j = 0; j < word.length(); j++)
{
randCH = word.substr(rand() % length, 1);
cout << randCH;
}
cout << " ";
cout << endl;
you can use std::next_permutation which is already built to achieve this:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string word;
cin >> word;
sort(word.begin(),word.end());
do {
cout << word <<endl;
} while(next_permutation(word.begin(),word.end()));
}

C++ Loops - inputting integers until user quits

well I'm trying to get the user to input an integers as much as they want, until they input a negative number. 1st step was to use the ATOF function to convert string to number(which I did), and then allow the user to input integers(I only manage to do once just to see if I can use the atof function correctly.
Any help/tips is appreciated on giving me the right direction.
Here is my code thus far:
#include <iostream>
#include <string>
int main() {
using namespace std;
char buffer[256];
char tempBuff[256] = {'\n'};
double result;
int count = 0;
cout << "Testing " << endl;
cout << "Enter Any integers: ";
cin.getline(buffer,256);
for(int i = 0; i < strlen(buffer); i++)
{
if(isdigit(buffer[i]))
{
tempBuff[count] = buffer[i];
count++;
}
}
if (atof(tempBuff) > 0) {
result = atof(tempBuff) / 2;
}
cout << endl << "The integer you put was: " << tempBuff
<< " And dividing the integers "<< result << endl;
cin.ignore();
return 0;
}
How is atof supposed to know how many valid digits tempBuff contains? The atof function only accepts a C-style string as its input. Otherwise, it has no way to know how many characters are valid.
You can use tempBuff[count] = 0; before the call of atof. A C-style string is terminated by a zero byte.