Hallo, ich möchte versuchsweise in C++ ein ASCII-Zeichen in einen String einlesen, dessen ASCII-Wert in einer Variable speichern und ausgeben. Hier z.B. das 'H': char val; stringstream ss (stringstream::in | stringstream::out); ss << 'H'; ss >> val; cout << val << endl; Funktioniert aber nicht. Fragen: Warum nicht? Wie kann man das auf einfache Weise machen? Danke schonmal.
Achja, auf der Konsole wird eben das Zeichen und nicht der Wert ausgegeben. Mit einer Integer-Variable funktioniert es auch nicht.
ich finde das streamzeug in c++ hässlich!!! Aber hier mein versuch der Lösung: char val; stringstream ss (stringstream::in | stringstream::out); ss << 'H'; ss >> val; cout << (_int8)val << endl;
> cout << val << endl; > Funktioniert aber nicht. Fragen: Warum nicht? Weil der Datentyp von val ein char ist. Und für char ist nun mal definiert, dass bei der Ausgabe nicht der Zahlenwert, sondern das Zeichen an sich ausgegeben wird.
Der Stringstream mag für dich jetzt nur eine Übung sein. Im Grunde brauchst du ihn hier nicht. Du musst nur dafür sorgen, dass der char bei der Ausgabe seine Sonderstellung verliert und als ganz normale Zahlenvariable angesehen wird. Peter hat ja schon gezeigt, wie man das mit einem Cast erzwingen kann. cout << (usnsigned int)'H' << endl;
@Karl heinz Buchegger
> (usnsigned int)'H'
kann das nicht schief gehen? (unsigned int) ist 2/4 byte gross 'H'
1Byte, das ganze ist ja ein Cast, kann es dabei nicht passieren das im
Speicher zu viele daten gelesen werden?
Peter wrote: > @Karl heinz Buchegger >> (usnsigned int)'H' > kann das nicht schief gehen? (unsigned int) ist 2/4 byte gross 'H' > 1Byte, das ganze ist ja ein Cast, kann es dabei nicht passieren das im > Speicher zu viele daten gelesen werden? Nein, da kann nichts schief gehen. Der Compiler weiss schon was in so einem Fall zu tun ist. Er ergänzt einfach die fehlenden Bytes mit 0-Bytes und schiebt erst dieses Zwischenergebnis in die Ausgabefunktion für unsigned int. Getreu dem Motto: Vor eine Zahl kann man beliebig viele führende Nullen stellen, es ändert nichts an der Zahl.
>Weil der Datentyp von val ein char ist. Und für char ist nun mal >definiert, dass bei der Ausgabe nicht der Zahlenwert, sondern das >Zeichen an sich ausgegeben wird. Wo ist denn sowas definiert? In der Iostream-Klasse? Euer Typecast funktioniert. Ich habe es mit int('H') hinbekommen. Gibt es einen Unterschied zwischen den Casting-Methoden (außer, das "(type) Wert" aus C herrührt?)
Nixwisser wrote: >>Weil der Datentyp von val ein char ist. Und für char ist nun mal >>definiert, dass bei der Ausgabe nicht der Zahlenwert, sondern das >>Zeichen an sich ausgegeben wird. > > Wo ist denn sowas definiert? In der Iostream-Klasse? Ja und Nein. In erster Linie ist es natürlich die Sprachdefinition von C++, die vorschreibt, was bei der Ausgabe eines char zu passieren hat. Aber ntürlich gibt es in den Stream-Klassen eine Funktion, die letztendlich den char einfach so ausgibt, während sie bei einem int (zb.) zuerst eine Textrepräsentierung des int erzeugt. > Euer Typecast funktioniert. Ich habe es mit int('H') hinbekommen. Gibt > es einen Unterschied zwischen den Casting-Methoden (außer, das "(type) > Wert" aus C herrührt?) Es läuft beides aufs gleiche hinaus. Rein syntaktisch macht deine Variante etwas anderes: int('H') erzeugt ein int Objekt, welches mit dem ASCII-Code von 'H' initialisiert wird. Dieses temporäre int-Objekt wird ausgegeben und dann wieder zerstört. Das ist aber reines theoretisches Geplänkel. In der Praxis läuft es aufs geliche hinaus und der Compiler wird auch in beiden Fällen identischen Code erzeugen. Interessant ist dieser Unterschied nur dann, wenn anstelle eines int tatsächlich mal ein 'richtiges' Objekt erzeugt werden muss.
>Das ist aber reines theoretisches Geplänkel. In der Praxis läuft es aufs >geliche hinaus und der Compiler wird auch in beiden Fällen identischen >Code erzeugen. Interessant ist dieser Unterschied nur dann, wenn >anstelle eines int tatsächlich mal ein 'richtiges' Objekt erzeugt werden >muss. Kannst du da mal ein Beispiel nennen?
Nixwisser wrote: >>Das ist aber reines theoretisches Geplänkel. In der Praxis läuft es aufs >>geliche hinaus und der Compiler wird auch in beiden Fällen identischen >>Code erzeugen. Interessant ist dieser Unterschied nur dann, wenn >>anstelle eines int tatsächlich mal ein 'richtiges' Objekt erzeugt werden >>muss. > > Kannst du da mal ein Beispiel nennen? Klar Wir brauchen dazu eine Klasse mit einem Konstruktor, der einen oder mehrere Werte übernimmt.
1 | class Fractional |
2 | {
|
3 | public:
|
4 | Fractional( int Nominator, int Denominator ) |
5 | : nomi_( Nominator ), |
6 | denomi_( Denominator ) |
7 | {}
|
8 | |
9 | private:
|
10 | int nomi_; |
11 | int denomi_; |
12 | };
|
und natürlich soll diese Klasse auch was machen. Sagen wir mal, wir verpassen ihr eine Funktion, die es ihr erlaubt, sich auf einen Stream auszugeben. Dazu noch einen freistehenden op<< der uns erlaubt, diese Funktion in gewohnter Syntax zu benutzen.
1 | class Fractional |
2 | {
|
3 | public:
|
4 | Fractional( int Nominator, int Denominator ) |
5 | : nomi_( Nominator ), |
6 | denomi_( Denominator ) |
7 | {}
|
8 | |
9 | void output( ostream& out ) const { out << ((double)nomi_) / denomi_; } |
10 | |
11 | private:
|
12 | int nomi_; |
13 | int denomi_; |
14 | };
|
15 | |
16 | std::ostream& operator<<( ostream& out, const Fractional& obj ) |
17 | {
|
18 | obj.output( out ); |
19 | return out; |
20 | }
|
und jetzt möchten wir gerne die beiden Zahlen 5 und 8 als Bruch auffassen (dazu ist ja die Klasse Fractional gedacht) und den Wert des Bruchs in Zahlenform ausgeben
1 | int main() |
2 | {
|
3 | std::cout << Fractional( 5, 8 ) << endl; |
4 | }
|
Hier wird ein temporäres Fractional Objekt erzeugt, mit den Werten 5 und 8 initialisiert. Dieses temporäre Fractional Objekt wird aufgefordert sich auf den Stream auszugeben (wobei op<< benutzt wird) und dann zerstört sich das temporäre Objekt wieder. Edit: Ach ja. Hier muss man über ein temporäre Objekt gehen. Mit simplen Casting kommt man hier nicht weiter.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.