2016-03-18 11 views
0

Ich versuche, den Operator >>, um eine Überlastung ein einzelnes (erstellt mit enum Symbol {e,a,b,c,d};) Symbol zu lesen:strchr Verwendung zu überlasten >>

istream & operator >> (istream & is, Symbol & sym) { 
    Symbol Arr[]={e,a,b,c,d}; 
    char ch; 
    is>>ch; 
    if (strchr("eabcd",ch)) 
    sym=Arr[ch-'e']; 
     else { 
     is.unget(); 
     is.setstate(ios::failbit); 
     } 
    return is; 
} 

Aber dies liest einige Müll (Zahlen) statt, was ich Suche nach, was zu einer Segmentierung Fehler beim Versuch, es mit meiner < < Überladung zu drucken, was mache ich falsch? Edit: Oh, und natürlich habe ich using namespace std; am Anfang hinzugefügt, gleich mit einschließlich iostream und cstring.

+0

Nur neugierig, welches Problem möchten Sie lösen? – Incomputable

+0

Dies ist Teil eines größeren Projekts für meine Object Programming Kurs an einer Universität, ich muss Symbole lesen, um dann Operationen an ihnen mit einer Additionstabelle usw. –

Antwort

1

Hier stimmt ein paar Dinge nicht. Lasst uns zuerst eure Verstrebungen reparieren. Verwenden Sie immer nur Klammern. Es ist sehr schwierig zu sehen, was mit was aufgereiht ist:

istream & operator >> (istream & is, Symbol & sym) { 
    Symbol Arr[]={e,a,b,c,d}; 
    char ch; 
    is>>ch; 
    if (strchr("eabcd",ch)) { 
     sym=Arr[ch-'e']; 
    } 
    else { 
     is.unget(); 
     is.setstate(ios::failbit); 
    } 
    return is; 
} 

Ok groß. Was passiert nun, wenn der Benutzer etwas wie 'a' eingibt? Die strchr ist erfolgreich, und dann tun Sie sym = Arr[ch - 'e']. Aber ch - 'e' in diesem Fall ist -4. Das ist irgendwo ein völlig zufälliges Stück Speicher, also bekommst du Müll. Um tatsächlich strchr verwenden, müssen Sie tun so etwas wie:

const char* options = "eabcd"; 
if (const char* p = strchr(options, ch)) { 
    sym = Arr[p - options]; 
} 

Aber das ist irgendwie schrecklich. Ich würde vorschlagen, nur einen Schalter mit:

switch (ch) { 
    case 'e': sym = e; break; 
    case 'a': sym = a; break; 
    ... 
    default: 
     is.unget(); 
     is.setstate(ios::failbit); 
} 

Auch, is >> ch könnte scheitern und Sie nicht, dass die Überprüfung. Sie sollten:

istream& operator>>(istream& is, Symbol& sym) { 
    char ch; 
    if (is >> ch) { 
     switch(ch) { ... } 
    } 
    return is; 
} 
+0

Aber warum ist es "-4" und nicht 1? 'a' kommt nach' e' in meinem Code, missverstehe ich, wie 'strchr' funktioniert? –

+0

@GizmoofArabia Sie subtrahieren 'Char's. Dein Enum ist irrelevant. – Barry

+0

@GIzmoofArabia, Nein. Wenn Sie Substruktionen ausführen, ist 'a' - 'e' negativ, weil Sie ASCII-Code-Substruction ausführen. Sehen Sie sich [ASCII-Codes] an (http://www.asciitable.com/). Sehen Sie sich die Spalten dec und char an. – Incomputable

0

Wenn ch ist 'a', ch - 'e' (97-101) eine negative Zahl (-4) werden, was den Zugriff auf das Array Arr außerhalb der Grenzen führen wird. Das führt zu undefiniertem Verhalten.

switch (ch) 
{ 
    case 'a': 
     sym = a; 
     break; 

    case 'b': 
     sym = b; 
     break; 

    case 'c': 
     sym = c; 
     break; 

    case 'd': 
     sym = d; 
     break; 

    case 'e': 
     sym = e; 
     break; 

    default: 
    // Nothing to do 
    break; 
} 

Wenn Sie Arr verwenden möchten, müssen Sie Arr definieren:

Symbol Arr[]={a,b,c,d,e}; 

Die Art und Weise Sie Ihre Symbole haben, werden Sie eine switch Anweisung verwenden müssen Dann können Sie auf das Array wie folgt zugreifen und die switch Anweisung vermeiden:

sym=Arr[ch-'a']; // ch - 'a' is 0 when ch is 'a' 
        // ch - 'a' is 4 when ch is 'e'. 
+0

'' e '- ch' wird nicht funktionieren, weil die Elemente von ' Arr' sind nicht in der Reihenfolge von "e" bis "a". –

+0

@RemyLebeau, danke für den Hinweis auf den Fehler. Es ist jetzt behoben. –