2017-12-27 3 views
1

Ich schrieb ein kleines Musikprogramm unter Windows zum Spaß. Ich fand den Teil des Codes falsch. Dies ist der minimierte Code (MCVE) zur Wiedergabe des Problems:Seltsames Verhalten für überlastete I/O-Operator in Klasse

#include <iostream> 
using std::istream; 
using std::cin; 
using std::cout; 
using std::cerr; // Debug output goes to stderr 
using std::endl; 

class Key { 
    public: 
    typedef signed char Pitch, Octave; // -128 to 127 
    typedef signed long Absolute; // -2147M to 2147M 
    Pitch p; 
    Octave o; 

    public: 
    Key(const Pitch& _p, const Octave& _o) : 
     p(_p), o(_o) {} 
    Key(void) : Key(Pitch(0), Octave(0)) {}; 
    Absolute abs(void) const { 
     return 12L * Absolute(o) + Absolute(p); 
    } 
    friend istream& operator>> (istream&, Key&); 
}; 

istream& operator>> (istream& is, Key& k){ 
    return (is >> k.p >> k.o); 
} 

Und hier ist das Laufteil:

Key k; 
cin >> k; 
cout << k.abs() << endl; 

Da der Eingang 0 0 wird der Ausgang soll 0 sein, aber die tatsächliche Ausgabe ist lächerlich groß (624). Ich habe versucht, diese

cerr << k.p << k.o << endl; 

Und der Ausgang ist 00 (kein Raum zwischen siehe Code), wie erwartet.

+0

@StoryTeller Es ist meine Schuld. Ich habe meinen PC nach dem Programmieren heruntergefahren und bin (wie üblich) im Internet auf meinem 5,5 "Android-Handy, einschließlich SO, gelaufen. Ich habe den Code neu geschrieben, so dass in Fragen und Antworten neue Tippfehler auftreten. – iBug

+0

In Ordnung ist jetzt richtig, keine schlechte Frage – StoryTeller

Antwort

1

is >> k.p hat ein besonderes Verhalten, weil k.p Zeichentyp hat. Der Eingang 0 erzeugt das Zeichen '0', nicht den Wert 0. In technischer Hinsicht hat die Überladung von std::istream::operator>> dieses unterschiedliche Verhalten, wenn das Argument der rechten Hand einen Zeichentyp hat.

So Eingabe 0 0 auf einem ASCII-System würde Ausgabe 48 * 12 + 48 generieren, die zufällig 624 ist.

Wahrscheinlich möchten Sie in eine int-Variable einlesen und dann in den Bereich k.p konvertieren (mit einer Fehlerbehandlung bei Eingabe außerhalb des Bereichs).

+0

Die Debug-Ausgabe hat mich wirklich verwirrt.Wenn es '0 [Space] wäre, hätte ich sofort den Fehler entdeckt.So ist es dann' 00' anstatt '0 [Space]'? – iBug

+0

Sie fragen, warum 'cout << kp << ko 'gibt' 00 'und nicht' 0 0 'aus? Sie haben zu keinem Zeitpunkt ein Leerzeichen ausgegeben ... –

+0

Nein. Da ich zwei Zeichen gelesen habe, warum ist' nn ' t die Sekunde ein Leerzeichen (das nächste Zeichen, eine andere Null, im Stream lassen), aber die Null, die übrig sein sollte? – iBug