2017-07-25 11 views
-2

Greetings to StackOverflowのコミュニティ!私は真剣に誰かの助けが必要です。
ここには、指定された文字列(str)の最短文のシンボルの最初と最後のインデックスである2つの整数を出力するはずのコードがあります。 ご覧のとおり、この文字列の最短文は "Hey !!!"です。文字 'H'のインデックスは16、最後の感嘆符のインデックスは21なので、正しい出力は次のようになります。16 21.
私はCppShell(cpp.sh)を使って自分のコードをコンパイルしました。同じコンパイラがそれを構築するために、それぞれの新しい試みで異なる結果が得られます。

試み#1:16 21
試み#2:145921712 4196790
試み#3:16 21
試行#4:16 21
試行# 5:1453219648 4196790
など

誰か私にこの奇妙な状況を教えてください。私はC++の初心者ですから、私のコードでは間違いがないかもしれません。C++:同じコードとコンパイラですが、各ビルド後の出力が異なります

#include <iostream> 
#include <cstdlib> 
#include <clocale> 
#include <cstdio> 
#include <cstring> 

using namespace std; 

int main() 
{ 
    setlocale(LC_CTYPE, "rus"); 

    char str[] = "  What's up? Hey!!! It's a practice... How are you?? "; 
    char* ptr = str; 
    char* p = ptr; 

    int startsym, endsym; 
    int startsymMin = 0, endsymMin = 2000; 

    while(*ptr) 
    { 
     if (*ptr > 64 && *ptr < 91) // capitalized letters 'A'-'Z' 
     { 
      startsym = strchr(ptr, *ptr)-p; 

      while(*ptr) 
      { 
       if ((*ptr == '!' && *(ptr+1) != '!' && *(ptr+1) != '?') 
        || (*ptr == '?' && *(ptr+1) != '!' && *(ptr+1) != '?') 
        || (*ptr == '.' && *(ptr+1) != '.')) 
       { 
        endsym = strchr(ptr, *ptr)-p; 
        break; 
       } 
       ptr++; 
      } 
     } 

     if (endsym - startsym < endsymMin - startsymMin) { 
      startsymMin = startsym; 
      endsymMin = endsym; 
     } 

     ptr++; 
    } 

    cout << startsymMin << " " << endsymMin << endl; 

    return 0; 
} 
+2

多くのコードは、未定義の動作を提供します。例えば、 'ptr ++'はポインターの中のアドレスを追加し、ポインターの実際の値は追加しません。 C++では、charの配列の代わりにstd :: stringを使用することをお勧めします。 –

+2

@mikebaykoそれはかなり一般的で、よく定義されています(多分C++のishではなく、Cの共通のイディオムです) –

+2

ループの最初の繰り返しを見てください。最初の 'if'はfalseで、2番目の' if'では、初期化されていない変数( 'startsym'、' endsym')を使います。 – geza

答えて

2

ループの最初の繰り返しを見てください。最初のifはfalseで、次に2番目のifでは、初期化されていない変数(startsym,endsym)を使用します。

これらの変数も同様に初期化すれば、プログラムは正常に動作します。このサンプルストリングについては、少なくとも(私はこのプログラムがすべての文字列に対して正常に動作するように、他のエッジケースを解決する必要があると思います)。

ヒント:

  • あなたのプログラムが誤動作理由を見つけるためにデバッガを使用(ただし、 は残念ながら、この特定のケースでは、デバッガは問題は何あなたに を教えてくれないかもしれません)。
  • あなたはMSVCを使用している場合、あなたは初期化されていない変数のランタイムチェックをオンにすることができますが(/ RTCu)
  • Linuxを使用している場合、このエラー(およびエラーの他の種類の多くを)キャッチするvalgrindのを使用することができます
+0

これは助けになりました!どうもありがとう! – vitdev

関連する問題