mikrocontroller.net

Forum: PC-Programmierung Wert eines characters ausgeben


Autor: Nixwisser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Nixwisser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achja, auf der Konsole wird eben das Zeichen und nicht der Wert 
ausgegeben. Mit einer Integer-Variable funktioniert es auch nicht.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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;

Autor: teplotaxl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
du brauchst itoa

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>  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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
teplotaxl wrote:
> du brauchst itoa

Quatsch

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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;

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Nixwisser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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?)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Nixwisser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.
class Fractional
{
  public:
    Fractional( int Nominator, int Denominator )
    : nomi_( Nominator ),
      denomi_( Denominator )
    {}

  private:
    int nomi_;
    int denomi_;
};

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.
class Fractional
{
  public:
    Fractional( int Nominator, int Denominator )
    : nomi_( Nominator ),
      denomi_( Denominator )
    {}

   void output( ostream& out ) const { out << ((double)nomi_) / denomi_; }

  private:
    int nomi_;
    int denomi_;
};

std::ostream& operator<<( ostream& out, const Fractional& obj )
{
  obj.output( out );
  return out;
}

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
int main()
{
  std::cout << Fractional( 5, 8 ) << endl;
}

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.

Autor: Nixwisser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Besten Dank!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.