Forum: PC-Programmierung Zeichen als Zahl ausgeben


von Ingo L. (grobian)


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
1
#include <iostream>
2
#include <fstream>
3
#include <string>
4
using namespace std;
5
char zeichen;
6
7
int main()
8
{
9
  ifstream dateilesen;
10
  string dateiname;
11
  cout << "DATEINAME : " ;
12
  cin >> dateiname;
13
  dateilesen.open(dateiname.c_str(), ios_base::in);
14
15
  if(!dateilesen)
16
   {
17
     cout << "Datei nicht vorhanden";
18
     cout << endl;
19
   }
20
  
21
  
22
  else   
23
   {
24
   while (!dateilesen.eof())
25
        {
26
         dateilesen.get(zeichen);
27
         cout << zeichen;
28
         cout << " ";
29
        }
30
   }
31
        
32
  dateilesen.close();
33
  system("PAUSE");    
34
  return EXIT_SUCCESS;
35
}

von Ingo L. (grobian)


Lesenswert?

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

1
{
2
   while (!dateilesen.eof())
3
        {
4
         dateilesen.get(zeichen);
5
         cout << (int) zeichen;
6
         cout << " ";
7
        }
8
}

von Karl H. (kbuchegg)


Lesenswert?

Ingo Laabs schrieb:
> gut, dass habe ich jetzt so gelöst..aber warum wird mir der letzte Wert
> doppelt bzw. 2 mal  ausgegeben ??
>
>
>
1
> {
2
>    while (!dateilesen.eof())
3
>         {
4
>          dateilesen.get(zeichen);
5
>          cout << (int) zeichen;
6
>          cout << " ";
7
>         }
8
> }
9
>

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 
:-)

von Karl H. (kbuchegg)


Lesenswert?

Und so muss das richtig aussehen
1
{
2
   while( dateilesen.get(zeichen) )
3
   {
4
     cout << (int) zeichen;
5
     cout << " ";
6
   }
7
8
   if( !dateilesen.eof() )
9
     cout << "Fehler beim lesen der Datei\n";
10
}

von Karl H. (kbuchegg)


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

von Ingo L. (grobian)


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

von Karl H. (kbuchegg)


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;

von Ingo L. (grobian)


Angehängte Dateien:

Lesenswert?

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

mit:
1
{
2
    dateilesen.get(zeichen);
3
    cout << zeichen <<"=";
4
    cout << (int) zeichen;
5
    cout << " ";
6
  }

von Karl H. (kbuchegg)


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:
>
>
1
> {
2
>     dateilesen.get(zeichen);
3
>     cout << zeichen <<"=";
4
>     cout << (int) zeichen;
5
>     cout << " ";
6
>   }
7
>

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.

von Ingo L. (grobian)


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
1
   for (a=0; a <=43; a++) 
2
     {
3
       dateilesen.get(zeichen);
4
       tabelle[a]=(int)(unsigned char) zeichen;
5
     }
6
   
7
   cout << "Datentyp : " << endl;
8
   for (a=0; a <=3; a++) 
9
      {
10
       cout <<  tabelle[a] << endl; 
11
      } 
12
        
13
  dateilesen.close();
14
  system("PAUSE");    
15
  return EXIT_SUCCESS;

von Karl H. (kbuchegg)


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
1
...
2
3
  int Data[ ANZAHL_ELEMENTE ];
4
5
...
6
7
  for( index = 0; index < ANZAHL_ELEMENTE; ++index )
8
  {
9
    // mach was mit Data[index]
10
  }

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++ )

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
Noch kein Account? Hier anmelden.