回答两个编译器的区别

时间:2016-02-01 15:58:11

标签: c++ compiler-errors

我编译了以下代码,但是我遇到了一个严重的问题。 当我在visual studio 2015中编译此代码时,它完美地运行。 但是,当我在Dev C ++中编译此代码时,我认为它不会打印“是”作为答案。

例如,当我输入像

这样的单词时
  1. lol
  2. 是我看过的车还是猫?
  3. abcdefghiihgfedcba
  4. 这些输入必须返回yes,但在dev c ++中返回no。

    为什么会出现此问题?

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

2 个答案:

答案 0 :(得分:4)

由于您使用的是未初始化的数据,因此您的程序会显示未定义的行为。

你有:

char text[256], fixed[256];

是未初始化的数组。然后你去使用以下方式访问它们:

for (int i = 0; i < sizeof(text); i++) {
   text[i] = toupper(text[i]); // Accessing uninitialized array
}

您可以使用以下几种方法修复它:

  1. 初始化数组。

    char text[256] = {0}, fixed[256] = {0};
    
  2. 仅访问getline

    调用中填写的元素
    size_t size = strlen(text);
    for (int i = 0; i < size; i++) {
    
  3. 但是,更好的解决方法是始终使用第二种方法。这样,您就不会处理不必要的数据。

答案 1 :(得分:1)

使用std::string作为strlen()的替代是相当奇怪的,当你可以更好地使用它时:

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

当然,您的程序可以简化,但我尝试将其保持接近原始版本以显示为什么在C ++中使用std::string而不是旧样式char[]更好

这里使用std::string和标准库中的其他algos的simnpliefied版本:

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