Unerwartetes Stream-Verhalten bei Typ (unsigned char)?!
-
Hallo zusammen,
ich muss eine ASCII-Datei einlesen, welche Daten in einer tabellarischen Form speichert. Die Werte werden mit Leerzeichen getrennt. Eine neue Zeile wird durch ein Newline markiert.
Eine Datei vom Datentyp unsigned char mit drei Spalten und vier Zeilen sähe somit folgendermaßen aus:
143 156 3 255 0 54 98 23 254 75 1 23und eine vom Typ double:
1,54 54,23 1,4 1 87,435 2334,242 0 65,31 13 5123,23 976,1 12,32Nachdem ich den Dateistream (ifstream) geöffnet habe, lese ich die Werte ein:
while( file.good() ) { string row; T val; // T ist ein Template-Parameter getline( file, row ); istringstream stream( row ); while( stream.good() ) { stream >> val; // irgendwas mit val anstellen... } }Nun dies funktioniert soweit auch ganz gut, solange der Datentyp von T nicht (unsigned) char ist
Denn dann scheint der >> Operator anders zu arbeiten. Nun liest er die Datei zeichenweise ein, anstatt bis zum nächsten Whitespace oder Newline zu lesen und diese Zeichen als den entsprechenden Datentyp zu interpretieren. D.h. bei unsigned char und dem Dateibeispiel von oben würde ich bei drei Durchläufen der inneren Schleife 1, 4 und 3 erhalten, anstatt beim ersten Durchlauf 143.Gibt es eine Möglichkeit dem Stream beizubringen, dass er sich so verhalten soll wie bei allen anderen Datentypen auch??
Vielen Dank für jede Hilfe!

-
Spezialisier dein Template für (unsigned) char, lies ints ein und caste sie nach (unsigned) char. Ein Char ist per se ein Zeichen, keine Zahl.
-
Und eine andere Möglichkeit, ausser einer Template-Spezialisierung und einem cast nach int gibt es nicht?
-
Welches Problem hast Du denn mit der Template-Spezialisierung? Das wäre im Prinzip die einfachste Möglichkeit. Ein Flag für die IOstreams, die das trotzdem als Zahl und nicht als Zeichen lesen, gibt es afaik nicht.
-
Wenn ich eine Template-Spezialisierung benutze, bekomme ich beim Linken eine "multiple definition" Fehlermeldung. Angeblich sei die Methode für <unsigned char> in zwei .o Dateien definiert, welche kollidieren.
Compiler ist GCC 3.3.6.
-
7H3 N4C3R schrieb:
Ein Char ist per se ein Zeichen, keine Zahl.
Wenn du dir mal ne char_traits Klasse ansiehst wirst du feststellen dass ein char beides ist/sein kann.
Ansonsten würde ich mal mein Glück mit nem istream_iterator probieren.
MfG Spacelord
-
wenn du nur zahlentypen einlesen willst, dann kannst du es ja so machen:
while( file.good() ) { string row; T val; // T ist ein Template-Parameter getline( file, row ); istringstream stream( row ); while( stream.good() ) { double num; stream >> num; val=static_cast<T>(num); // irgendwas mit val anstellen... } }
-
Spacelord schrieb:
Wenn du dir mal ne char_traits Klasse ansiehst wirst du feststellen dass ein char beides ist/sein kann.
Wie Du im Standard unter 27.6.1.2.2 sehen kannst, gibt es aber keinen Arithmetic Extractor für char.
Man könnte mal versuchen, das num_get<> Template selbst zu benutzen... probier ich mal aus. Falls es klappt, poste ich den Code.
Edit:
Hm zumindest im ersten Versuch mit nem halbwegs aktuellen GCC gibt's keine Version von num_get für char.Edit2:
Und der Standard sieht auch keine Methode in num_get vor, um chars als Zahlen zu lesen. Also wäre Spezialiserung immernoch die beste Möglichkeit.@caffeine:
Naja die Verwendung einer Template-Spezialisierung sollte aber nicht zu multiple definitions führen. Zeig mal den Code, der das macht.
-
Könnte man hier nicht vielleicht von num_get ableiten und es um char, unsigend char, signed char entsprechend erweitern? Oder ein eigenes facet schreiben?
Hume?

-
facet geht immer. Ist aber von kosten-nutzen Faktor relativ weit unten anzusiedeln.
//edit was schreib ich da: das geht nicht! der op>> sucht sich nämlich gleich das "passende" facet aus, und das wird bei char nie num_get sein.
-
Natürlich dann nicht mehr op>> benutzen, sondern direkt das facet.
-
7H3 N4C3R schrieb:
Natürlich dann nicht mehr op>> benutzen, sondern direkt das facet.
dann ist der kosten-nutzen faktor nahe null

kann ich gleich nach int casten und dann wieder nach char zurück
