Reputation: 85
I compiled the following code, But I got a serious problem. When I compiled this code in visual studio 2015, It works perfectly. However When I compile this code in Dev C++, I think it doesn't print "Yes" as an answer.
For example, when I type words like,
these inputs must return yes, but in dev c++ returns no.
Why does this problem occur?
#include <iostream>
#include <string>
using namespace std;
bool is_palindrome(char input[], int numOfSlots);
int main(void) {
char text[256], fixed[256];
cin.getline(text, sizeof(text), '\n');
for (int i = 0; i < sizeof(text); i++) {
text[i] = toupper(text[i]);
}
int j = 0;
for (int i = 0; i < sizeof(text); i++) {
if ((text[i] >= '0' && text[i] <= '9') || (text[i] >= 'A' && text[i] <= 'Z')) {
fixed[j] = text[i];
j++;
}
}
fixed[j] = '\0';
string s_fixed = fixed;
if (is_palindrome(fixed, s_fixed.length()) == true) {
cout << "Yes";
}
else {
cout << "No";
}
return 0;
}
bool is_palindrome(char input[], int numOfSlots) {
int i = 0;
while (i < numOfSlots / 2)
{
if (input[i] != input[(numOfSlots - 1) - i])
return false;
i++;
}
return true;
}
Upvotes: 1
Views: 140
Reputation: 44268
using std::string
as replacement of strlen()
is rather strange, when you can use it much better way:
bool is_palindrome( const std::string &input );
int main(void) {
std::string text;
getline(cin,text);
for (size_t i = 0; i < text.length(); i++) {
text[i] = toupper(text[i]);
}
std::string fixed;
for (size_t i = 0; i < text.length(); i++) {
if ((text[i] >= '0' && text[i] <= '9') || (text[i] >= 'A' && text[i] <= 'Z')) {
fixed += text[i];
}
}
if (is_palindrome(fixed)) {
cout << "Yes";
}
else {
cout << "No";
}
return 0;
}
bool is_palindrome(const std::string &input) {
size_t numOfSlots = input.length();
int i = 0;
while (i < numOfSlots / 2)
{
if (input[i] != input[(numOfSlots - 1) - i])
return false;
i++;
}
return true;
}
of course your program can be simplified but I tried to keep it close to original to show why it is better to use std::string
instead of old style char[]
in C++
Here simnpliefied version using std::string
and other algos from standard libraries:
#include <iostream>
#include <string>
#include <algorithm>
bool is_palindrome( std::string str )
{
if( str.empty() ) return false;
std::transform( str.begin(), str.end(), str.begin(), []( char c ) { return std::toupper( c ); } );
str.erase( std::remove_if( str.begin(), str.end(), []( char c ) { return !std::isalnum( c ); } ), str.end() );
auto len = str.length() / 2 + 1;
return std::string( str.begin(), std::next( str.begin(), len ) ) ==
std::string( str.rbegin(), std::next( str.rbegin(), len ) );
}
int main()
{
std::string text;
std::getline( std::cin, text );
std::cout << ( is_palindrome( text ) ? "yes" : "no" ) << std::endl;
return 0;
}
Upvotes: 1
Reputation: 206717
Your program exhibits undefined behavior since you are using uninitialized data.
You have:
char text[256], fixed[256];
which are uninitialized arrays. And then you go to access them using:
for (int i = 0; i < sizeof(text); i++) {
text[i] = toupper(text[i]); // Accessing uninitialized array
}
You can fix it using couple of ways:
Initialize the arrays.
char text[256] = {0}, fixed[256] = {0};
Access only the elements that were filled in the call to getline
.
size_t size = strlen(text);
for (int i = 0; i < size; i++) {
However, the better fix is to always use the second method. That way, you don't process unnecessary data.
Upvotes: 4