sscanf und Leerzeichen
-
Hallo!
Ich habe schon diverse threads zu dem Thema gelesen aber für mein Problem nichts passendes gefunden.
Ich möchte einen String einlesen, in dem die Werte (char, int und float) in festen Breiten angeordnet sind.
Damit ich die Werte sauber trennen kann mache ich das mit sscanf.
Es kann aber vorkommen, daß ein Datenfeld leer ist (= aus lauter Leerzeichen besteht).Dann überliest sccanf das leere Datenfeld und ordnet dann die nachfolgenden Werte falsch zu.
Kann ich sscanf irgendwie "zwingen" die leeren Datenfelder auch zu lesen und denen dann einen entspr. Wert zuzuordnen?
Ciao
OkkaPapa
-
Wenn du feste Breiten hast, kannst du keine variabel reagierenden C-Funktionalitäten dafür benutzen.
sscanf bietet sich an, erstmal alles in (Teil)Strings lesen (dafür gibst du die Feldbreite jeweils im Formatstring an), und dann die Teilstrings weiter auswerten (Umwandeln in Zahlen u.ä. musst du dann eben selbst machen...)int main() { const char *s0="11112222 3335"; const char *s1="1111 3335"; char a[100],b[100],c[100]; sscanf(s0,"%4[^\n]%4[^\n]%4[^\n]",a,b,c); printf("===\n%s\n===\n%s\n===\n%s\n",a,b,c); sscanf(s1,"%4[^\n]%4[^\n]%4[^\n]",a,b,c); printf("===\n%s\n===\n%s\n===\n%s\n",a,b,c); return 0; }
-
Hallo!
Danke für die Hilfe, aber was mache ich da eigentlich?
Das Format %4[^\n] kenne ich so noch nicht...
Ciao
OkkaPapa
-
OkkaPapa schrieb:
Danke für die Hilfe, aber was mache ich da eigentlich?
Das Format %4[^\n] kenne ich so noch nicht...
http://http://www.cplusplus.com/reference/cstdio/scanf
Das ist das "negated scanset". Dieses wird durch
[^
eingeleitet und durch]
beendet. Dann wird wie eine Zeichenkette eingelesen. Der Lesevorgang stoppt, wenn ein Zeichen zwischen den Klammern gelesen wird. Hier ist dieses Zeichen nur '\n', also der Zeilenumbruch.Zusätzlich wurde hier ein width-Feld angegeben. Das heißt, es werden maximal vier Zeichen gelesen, selbst wenn dabei kein '\n' gefunden wird. Vorsicht: Am Ende wird in jedem Fall* noch ein Nullterminatorzeichen an die Zeichenkette angehängt, es muss also Platz für 5 Zeichen vorhanden sein.
*: Das heißt sowohl bei Abbruch des Lesevorgangs, weil eines der Trennzeichen gefunden wurde, als auch bei Abbruch weil die maximale Anzahl Zeichen gelesen wurde.
-
Ich würde die Werte, da ja feste Feldlängen, in Einzelfelder übertragen, schaun, ob gefuellt - also nicht space - und dann entsprechend weiterverarbeiten mit atoi, atof usw...
Oder gleich Opencobol nehmen und nen entsprechenden Satz in der fd definieren.
Die Leerfelder dann mit if .. not numeric move zero ordentlich initialisieren.
-
zwischenpuffer sind nicht nötig, du kannst direkt konvertieren.
jedes der 3 felder im string mit den 3 datentypen hat n bytes und die reihenfolge der von dir angegebenen 3 datentypen ist
char, int, float(andernfalls ändere entsprechend sinngemäß die folgende vorgehensweise):kopiere n zeichen (strncpy) in ein 0-terminiertes feld der größe n+1 bytes.
speichere das zeichen an postition 2n.
überschreibe das zeichen an postition 2n mit 0.
konvertiere (per atoi o.ä.) die integer-zahl ab position n.
schreibe das gespeicherte zeichen zurück an position 2n.
konvertiere (per atof, strtod o.ä.) die float-zahl ab position 2n.das überschreiben eines zeichens an der position einer feldgrenze(hier 2n) mit einer 0 stellt sicher,
das eine konvertierungsfunktion wie atof, strtod, atoi, etc. den konvertierungsvorgang abbricht.
-
Mach es doch Rückwärts! Kein umständliches Zwischenspeichern von überschriebenen Zeichen.