2016-11-13 21 views
-3

Der folgenden Code zunehmende Größe Schnipsel Ausgang unterschiedliche Ergebnisse für den gleichen Eingang (7.747.774):Leere Zeichenkette durch eine in C++

A:

#include <iostream> 
#include <string> 
#include <algorithm> 
using namespace std; 

int main() { 
    string N; 
    cin >> N; 

    int K = count(N.begin(), N.end(), '4') + count(N.begin(), N.end(), '7'); 
    string C = to_string(K); 
    bool lucky = (K>0) && (count(C.begin(), C.end(), '4') + count(C.begin(), C.end(), '7') == C.size()); 
    cout << (lucky?"YES":"NO") << endl; 

    return 0; 
} 

B:

#include <iostream> 
#include <string> 
#include <algorithm> 
using namespace std; 

int main() { 
    string N; 
    cin >> N; 

    int K = count(N.begin(), N.end(), '4') + count(N.begin(), N.end(), '7'); 
    string C = "" + K; 
    bool lucky = (K>0) && (count(C.begin(), C.end(), '4') + count(C.begin(), C.end(), '7') == C.size()); 
    cout << (lucky?"YES":"NO") << endl; 

    return 0; 
} 

A Druck JA, während B NO druckt, da die Größe von "C" in B um eins erhöht wurde. Warum das?

+1

'" "+ K' ist nicht richtig, das ist nicht Java – yassin

+0

Nicht das Problem hier, aber Sie können einige Stress und zusätzliche Arbeit vermeiden, indem Sie SHOUTCASE Namen für Makros reservieren, und indem Sie in der Regel keine einzelnen Buchstaben verwenden. Die zwei Hauptausnahmen sind Schleifenzählervariablen, herkömmlich "i", "j" und "k", und ein Vorlagentypargument, herkömmlicherweise "T". Für letztere ziehe ich es vor, die Konvention zu brechen und 'Type' zu ​​schreiben. –

+1

@yassin: Es ist auch in Java ein schlechter Stil. Man sollte 'String.valueOf (K)' verwenden. –

Antwort

1

"" + K ist ein Vorgang zwischen einem und einem int. Es entspricht konzeptionell &(""[K])

Sie erstellen ein std::string von einem Zeiger, den Sie irrtümlicherweise erhalten haben. Es verweist auf einen nicht angegebenen Speicherort, und die Verwendung Ihres Konstrukts std::string beruht auf undefiniertem Verhalten.

Eine lustige Sache ist, dass, wenn Sie ein std::string wörtlichen verwenden sind, Sie einen Compiler-Fehler erhalten würden:

string C = ""s + K; 
2
string C = "" + K; 

nicht tut, was Sie denken, es tut. Sie denken wahrscheinlich, dass es std::to_string(K) entspricht, na ja. Was es tatsächlich ist, erhöht den Zeiger des Zeichenfolgenliterals "" von K.

Das ist undefiniertes Verhalten (wie K ist nicht 0 - das würde den Zeiger nicht ändern), und Sie können jedes Ergebnis erhalten. Sie müssen std::to_string oder std::atoi oder ähnliche Funktionen verwenden.

+2

Technisch ist "+ K" ein definiertes Verhalten, wenn "K" gleich Null oder Eins ist. (Im letzteren Fall zeigt der Zeiger nach dem Nullbyte am Ende der Zeichenkette.) Natürlich ist Dereferenzierung, dass der Nach-End-Zeiger, um ihn in eine Zeichenkette umzuwandeln, UB ist. –

+0

@MartinBonner Oh richtig, danke :) – Rakete1111

Verwandte Themen