www.mikrocontroller.net

Forum: PC-Programmierung Zeichen als Zahl ausgeben


Autor: Ingo Laabs (grobian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallöle !
ich habe unten aufgeführtes Programm welches mir die Datei einliest und 
das Zeichen ausgibt..aber als ASCII-Zeichen halt. Will aber den Wert der 
in der Datei steht haben. Was muss ich ändern ? besteht auch die 
Möglichkeit es als HEX auszugeben
Gruß aus Berlin
Ingo
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
char zeichen;

int main()
{
  ifstream dateilesen;
  string dateiname;
  cout << "DATEINAME : " ;
  cin >> dateiname;
  dateilesen.open(dateiname.c_str(), ios_base::in);

  if(!dateilesen)
   {
     cout << "Datei nicht vorhanden";
     cout << endl;
   }
  
  
  else   
   {
   while (!dateilesen.eof())
        {
         dateilesen.get(zeichen);
         cout << zeichen;
         cout << " ";
        }
   }
        
  dateilesen.close();
  system("PAUSE");    
  return EXIT_SUCCESS;
}

Autor: Ingo Laabs (grobian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gut, dass habe ich jetzt so gelöst..aber warum wird mir der letzte Wert 
doppelt bzw. 2 mal  ausgegeben ??

{
   while (!dateilesen.eof())
        {
         dateilesen.get(zeichen);
         cout << (int) zeichen;
         cout << " ";
        }
}

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

Bewertung
0 lesenswert
nicht lesenswert
Ingo Laabs schrieb:
> gut, dass habe ich jetzt so gelöst..aber warum wird mir der letzte Wert
> doppelt bzw. 2 mal  ausgegeben ??
>
>
>
> {
>    while (!dateilesen.eof())
>         {
>          dateilesen.get(zeichen);
>          cout << (int) zeichen;
>          cout << " ";
>         }
> }
> 

weil du den klassischen "Ich benutze eof um meine Schleife abzubrechen" 
Fehler gemacht hast.

Merkregel: C und C++ sehen nicht in die Zukunft. Ob eof vorliegt oder 
nicht, kann in C / C++ erst festgestellt werden, wenn ein Leseversuch 
schief gelaufen ist. (Stell dir einfach vor, dein Code liest nicht von 
einer Datei, sondern von einem Stream, der mit dem Benutzer verbunden 
ist. Wie soll eof wissen, ob da noch was kommt oder nicht?)


In C/C++ lautet das Idiom um einen Stream zu lesen immer so

   solange Leseversuch gut gegangen ist
       mach was mit den Daten

   warum ist die Schleife verlassen worden?
     Wenn es eof war, dann ist alles gut

Alle Lesefunktionen unterstützen dich in diesem Idiom, indem sie etwas 
zurückgeben, was sich als 'gut gegangen / nicht gut gegangen' verwenden 
lässt.
Das hat dann auch den Vorteil, dass die Schleife abbricht, sobald 
irgendetwas unvorhergesehen Fehlerhaftes auftritt und nicht nur im Falle 
eof.

Edit: Leider sieht man diese falsche Form auch des öfteren in Büchern 
:-)

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

Bewertung
0 lesenswert
nicht lesenswert
Und so muss das richtig aussehen
{
   while( dateilesen.get(zeichen) )
   {
     cout << (int) zeichen;
     cout << " ";
   }

   if( !dateilesen.eof() )
     cout << "Fehler beim lesen der Datei\n";
}

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

Bewertung
0 lesenswert
nicht lesenswert
Ingo Laabs schrieb:
> Hallöle !
> ich habe unten aufgeführtes Programm welches mir die Datei einliest und
> das Zeichen ausgibt..aber als ASCII-Zeichen halt. Will aber den Wert der
> in der Datei steht haben. Was muss ich ändern ? besteht auch die
> Möglichkeit es als HEX auszugeben


Sieh dir diese Seite an
http://www.willemer.de/informatik/cpp/iostream.htm

Autor: Ingo Laabs (grobian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
soweit klar.
Habe jetzt aber noch ein Problem mir der Zeile:

cout << (int) zeichen;

Die Zeichen mit dem ASCII Code über 127 ($7F) werden mir jetz als 
negative Zahlen ausgegeben.
Ein
cout << (uint) zeichen;
funktioniert hier irgendwie nicht mit dem DEVC++ Compiler

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

Bewertung
0 lesenswert
nicht lesenswert
Ingo Laabs schrieb:
> soweit klar.
> Habe jetzt aber noch ein Problem mir der Zeile:
>
> cout << (int) zeichen;
>
> Die Zeichen mit dem ASCII Code über 127 ($7F) werden mir jetz als
> negative Zahlen ausgegeben.
> Ein
> cout << (uint) zeichen;
> funktioniert hier irgendwie nicht mit dem DEVC++ Compiler
  ***************************

Kannst du das genauer spezifizieren?
Unter 'funktioniert irgendwie nicht' kann ich mir keinen konrekten 
Fehler vorstellen.

Offendbar ist char auf deinem Compiler per Default ein signed char.

  cout <<(uint)(unsigned char)zeichen;

Autor: Ingo Laabs (grobian)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
meine Werte 126,127,128,129 (die in der zu lesenden Datei stehen) kommen 
zu der im Anhang bebilderten Ausgabe

mit:
{
    dateilesen.get(zeichen);
    cout << zeichen <<"=";
    cout << (int) zeichen;
    cout << " ";
  }

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

Bewertung
0 lesenswert
nicht lesenswert
Ingo Laabs schrieb:
> meine Werte 126,127,128,129 (die in der zu lesenden Datei stehen) kommen
> zu der im Anhang bebilderten Ausgabe
>
> mit:
>
>
> {
>     dateilesen.get(zeichen);
>     cout << zeichen <<"=";
>     cout << (int) zeichen;
>     cout << " ";
>   }
> 

Das kann hinkommen, wenn char per Default ein signed Datentyp ist.

Du solltest es dir zur Regel machen:

* wenn du von einem Zeichen sprichst, ohne dass dich der Bytewert in
irgendeiner Form speziell interessiert, dann benutze char. Einfach nur
char. Das ist zb dann der Fall, wenn es sich einfach nur um Texte 
handelt.

* wenn du aber vorhast mit Bytes zu operieren, dann benutze immer
unsigned char. Du bist sonst (hilflos) dem Compiler ausgeliefert, ob der
char als signed oder unsigned ansieht. Auf dem einen Compiler läuft dein
Programm, so wie du dir das vorgestellt hast, auf einem anderen nicht.


In dem Fall castest du zeichen auf int. Da aber char anscheinend signed
war, bleibt natürlich auch das Vorzeichen erhalten.
An dieser Stelle willst du aber eigentlich ja einen Blick auf das Byte
hinter dem char erhaschen. Byte -> unsigned char.
Also vorher Zeichen auf unsigned char umcasten, damit bist du dann ein
eventuelles Vorzeichen los.

    cout << (int)(unsigned char) zeichen;

Das kostest auch zur Laufzeit nichts. Dieser cast beeinflusst lediglich,
wie der Compiler die Dinge auffasst und welche Operation er auswählt.

Autor: Ingo Laabs (grobian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nun lese ich einen bestimmten Teil der Datei in ein Array.
Wie kann ich auf einen definierten Bereich in dem Array zugreifen. Das 
Ding mit der Schleife ( for (a=0; a <=3; a++) ) scheint mir nicht so 
elegant
   for (a=0; a <=43; a++) 
     {
       dateilesen.get(zeichen);
       tabelle[a]=(int)(unsigned char) zeichen;
     }
   
   cout << "Datentyp : " << endl;
   for (a=0; a <=3; a++) 
      {
       cout <<  tabelle[a] << endl; 
      } 
        
  dateilesen.close();
  system("PAUSE");    
  return EXIT_SUCCESS;

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

Bewertung
0 lesenswert
nicht lesenswert
Ingo Laabs schrieb:

> Wie kann ich auf einen definierten Bereich in dem Array zugreifen. Das
> Ding mit der Schleife ( for (a=0; a <=3; a++) ) scheint mir nicht so
> elegant

Doch das ist genau das was man macht.

Aber gwöhn dir die <= Schreibwese ab! Du wirst früher oder später damit 
auf die Schnauze fallen.

In einer Schleife die bei 0 beginnt

     for( i = 0; i < 5; ++i )

steht in der Bedingung die Anzahl der Elemente, in diesem Fall 5, die 
bearbeitet werden.

Das Idiom lautet
...

  int Data[ ANZAHL_ELEMENTE ];

...

  for( index = 0; index < ANZAHL_ELEMENTE; ++index )
  {
    // mach was mit Data[index]
  }

Wenn du deine Schleifen so aufbaust, braucht kein C-Programmierer gross 
nachdenken, ob das jetzt stimmt oder nicht, ob du hinten aus dem Array 
raus fällst oder nicht, etc. In 2-zehntel Sekunden ist klar, dass das 
die Standardschleife über ein Array ist.

Wenn da was anderes als < steht, werden C-Programmierer hellhörig und 
fragen sich als erstes ob das wohl so sein muss, oder ob das ein Bug 
ist.


>    cout << "Datentyp : " << endl;
>    for (a=0; a <=3; a++)

Du willst die ersten 4 Elemente ausgeben

     for( a = 0; a < 4; a++ )

Du willst beginnend ab Index 5 die nächsten 7 Elemente ausgeben

     for( a = 5; a < 5 + 7; a++ )

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.