diff options
Diffstat (limited to 'doc')
| -rw-r--r-- | doc/csv.md | 19 |
1 files changed, 14 insertions, 5 deletions
| @@ -1,3 +1,4 @@ | |||
| 1 | |||
| 1 | # csv - CSV-Dateien parsen | 2 | # csv - CSV-Dateien parsen |
| 2 | 3 | ||
| 3 | - [x] korrekt | 4 | - [x] korrekt |
| @@ -40,7 +41,7 @@ for ( size_t nf; (nf = csv_read(&csv, in)) != 0; ) { /* eine Zeile aus `in` les | |||
| 40 | ~~~ | 41 | ~~~ |
| 41 | 42 | ||
| 42 | Es sind nur zwei Funktionen notwendig, um die Daten des FILE-Streams `in` vollständig zu verarbeiten: | 43 | Es sind nur zwei Funktionen notwendig, um die Daten des FILE-Streams `in` vollständig zu verarbeiten: |
| 43 | `csv_read()` liest eine Zeile aus dem Parameter `in` und liefert die Anzahl der erfolgreich geparsten Felder oder **`EOF`** bei Dateiende. | 44 | `csv_read()` liest eine Zeile aus dem Parameter `in` und liefert die Anzahl der erfolgreich geparsten Felder oder **0** bei Dateiende. |
| 44 | `csv_field()` liefert einen (read only) `const char`-Zeiger für das i-te Feld. | 45 | `csv_field()` liefert einen (read only) `const char`-Zeiger für das i-te Feld. |
| 45 | 46 | ||
| 46 | Der Speicher für das CSV-Objekt wird automatisch von `csv_read()` beim ersten Aufruf alloziert und wieder freigeben nachdem der Stream `in` vollständig gelesen wurde. | 47 | Der Speicher für das CSV-Objekt wird automatisch von `csv_read()` beim ersten Aufruf alloziert und wieder freigeben nachdem der Stream `in` vollständig gelesen wurde. |
| @@ -102,7 +103,7 @@ while ( csv_read(&csv, in) ) { | |||
| 102 | csv_cleanup(&csv); | 103 | csv_cleanup(&csv); |
| 103 | ~~~ | 104 | ~~~ |
| 104 | 105 | ||
| 105 | Dieser Code erzeugt ein neues `csv_t`-Objekt im Speicher welches anschließend mit `csv_init()` mit Standardwerten initialisiert wird. | 106 | Dieser Code erzeugt ein neues `csv_t`-Objekt im Speicher welches anschließend durch `csv_init()` mit Standardwerten initialisiert wird. |
| 106 | 107 | ||
| 107 | Dann wird der Datenstrom `in` zeilenweise in den Speicher eingelesen und innerhalb der Schleife verarbeitet. Die Anzahl der Felder pro Zeile wird mit Hilfe der Funktion `csv_nfields()` ermittelt. Alternativ liefert auch der Returnwert von `csv_read()` die Feldanzahl: | 108 | Dann wird der Datenstrom `in` zeilenweise in den Speicher eingelesen und innerhalb der Schleife verarbeitet. Die Anzahl der Felder pro Zeile wird mit Hilfe der Funktion `csv_nfields()` ermittelt. Alternativ liefert auch der Returnwert von `csv_read()` die Feldanzahl: |
| 108 | 109 | ||
| @@ -110,15 +111,16 @@ Dann wird der Datenstrom `in` zeilenweise in den Speicher eingelesen und innerha | |||
| 110 | // ... | 111 | // ... |
| 111 | size_t nf; | 112 | size_t nf; |
| 112 | while ( (nf = csv_read(&csv, in)) != 0 ) { | 113 | while ( (nf = csv_read(&csv, in)) != 0 ) { |
| 114 | assert(csv_nfiedls(&csv) == nf); | ||
| 113 | // ... | 115 | // ... |
| 114 | } | 116 | } |
| 115 | // ... | 117 | // ... |
| 116 | ~~~ | 118 | ~~~ |
| 117 | 119 | ||
| 118 | Der Rückgabewert 0 bei einem Aufruf von `csv_read()` kennzeichnet das Ende des Datenstroms. | 120 | Der Rückgabewert **0** bei einem Aufruf von `csv_read()` kennzeichnet das Ende des Datenstroms. |
| 119 | 121 | ||
| 120 | > **Hinweis:** | 122 | > **Hinweis:** |
| 121 | > Das Ende einer CSV-Datei mit 0-gelesenen Feldern zu kennzeichnen ist vollkommen legitim. Eine "leere" Zeile innerhalb der Datei würde nämlich als genau ein (leeres) Feld interpretiert, so dass der Rückgabewert hier 1 wäre. Anders gesagt: Es gibt in CSV-Dateien keine Zeilen mit 0 Feldern. | 123 | > Das Ende einer CSV-Datei mit 0-gelesenen Feldern zu kennzeichnen ist vollkommen legitim. Eine "leere" Zeile innerhalb der Datei würde nämlich als genau ein (leeres) Feld interpretiert, so dass der Rückgabewert hier **1** wäre. Anders gesagt: Es gibt in CSV-Dateien keine Zeilen mit 0 Feldern. |
| 122 | 124 | ||
| 123 | Der Aufruf von `csv_cleanup()` ist nicht zwingend notwendig, da alle belegten Ressourcen beim letzten `csv_read()` automatisch freigegeben werden, wenn es keinen Fehler bei der Dateiverarbeitung gab. | 125 | Der Aufruf von `csv_cleanup()` ist nicht zwingend notwendig, da alle belegten Ressourcen beim letzten `csv_read()` automatisch freigegeben werden, wenn es keinen Fehler bei der Dateiverarbeitung gab. |
| 124 | 126 | ||
| @@ -137,11 +139,14 @@ csv_t csv; | |||
| 137 | csv_init_opt(&csv, &csv_options); | 139 | csv_init_opt(&csv, &csv_options); |
| 138 | ~~~ | 140 | ~~~ |
| 139 | 141 | ||
| 140 | Damit wir nicht alle Felder in `csv_options` ändern müssen, initialisieren wir dieses zunächst mit `csv_default_options` und passen dann `field_delimiter` und `field_separator` an. Das `csv`-Objekt wird nun mit der Funktion `csv_init_opt()` initialisiert, die einen zusätzlichen Zeiger auf ein `csv_options_t`-Objekt erwartet. | 142 | Damit wir nicht alle Felder in `csv_options` ändern müssen, initialisieren wir dieses zunächst mit `csv_default_options` und passen dann `field_delimiter` und `field_separator` für unsere Bedürfnisse an. Das `csv`-Objekt wird nun mit der Funktion `csv_init_opt()` initialisiert, die einen zusätzlichen Zeiger auf ein `csv_options_t`-Objekt erwartet. |
| 141 | 143 | ||
| 142 | > **Hinweis:** | 144 | > **Hinweis:** |
| 143 | > `csv_init(&csv);` ist letztlich nur eine kürzere Schreibweise für `csv_init_opt(&csv, &csv_default_options);`. | 145 | > `csv_init(&csv);` ist letztlich nur eine kürzere Schreibweise für `csv_init_opt(&csv, &csv_default_options);`. |
| 144 | 146 | ||
| 147 | > **Hinweis:** | ||
| 148 | > Die Standardwerte für Feldtrenner und Feldbegrenzer lassen sich als Übersetzungsoptionen beim Compilieren über die Makros `CSV_DEFAULT_SEPARATOR` und `CSV_DEFAULT_DELIMITER` setzen. | ||
| 149 | |||
| 145 | Der Rest der Schleife bleibt gleich. | 150 | Der Rest der Schleife bleibt gleich. |
| 146 | 151 | ||
| 147 | **3\. Fehlerbehandlung hinzufügen** | 152 | **3\. Fehlerbehandlung hinzufügen** |
| @@ -354,6 +359,10 @@ Anschließend wird die Datei `csv-german.o` statt `csv.o` zum Projekt dazugelink | |||
| 354 | 359 | ||
| 355 | Die Headerdatei (`csv.h`) bleibt unverändert. | 360 | Die Headerdatei (`csv.h`) bleibt unverändert. |
| 356 | 361 | ||
| 362 | ### Speicherallokierer | ||
| 363 | |||
| 364 | TODO! | ||
| 365 | |||
| 357 | ## Lizenz | 366 | ## Lizenz |
| 358 | 367 | ||
| 359 | In den letzten Jahrzehnten habe ich massiv vom Internet und seinen Inhalten profitiert. Ein gutes Stück meiner Kenntnisse und Fähigkeiten verdanke ich den vielen Foren, Webseiten, Newsgroups und Individuen die Informationen und Software kostenfrei und allgemein zugänglich bereitstellen. | 368 | In den letzten Jahrzehnten habe ich massiv vom Internet und seinen Inhalten profitiert. Ein gutes Stück meiner Kenntnisse und Fähigkeiten verdanke ich den vielen Foren, Webseiten, Newsgroups und Individuen die Informationen und Software kostenfrei und allgemein zugänglich bereitstellen. |
