summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorThomas Schmucker <ts@its1.de>2020-07-06 10:53:44 +0200
committerThomas Schmucker <ts@its1.de>2020-07-06 10:53:44 +0200
commit4af184b6c696e08f9086531dd8ddd5ce3d59a96e (patch)
treef0a04b1a60a0de5d14c1075f31849b51de14233c /doc
parent2da1b85b56c33019802459663c309f49045bcd5d (diff)
downloadlibcsv-4af184b6c696e08f9086531dd8ddd5ce3d59a96e.tar.gz
libcsv-4af184b6c696e08f9086531dd8ddd5ce3d59a96e.tar.bz2
libcsv-4af184b6c696e08f9086531dd8ddd5ce3d59a96e.zip
Verschiebe die Dokumentation in ein eigenes Verzeichnis
Diffstat (limited to 'doc')
-rw-r--r--doc/csv.md198
1 files changed, 198 insertions, 0 deletions
diff --git a/doc/csv.md b/doc/csv.md
new file mode 100644
index 0000000..99beb5d
--- /dev/null
+++ b/doc/csv.md
@@ -0,0 +1,198 @@
1# csv - CSV-Dateien parsen
2
3- [x] korrekt
4- [x] einfach
5- [x] intuitiv
6- [x] schnell
7- [x] klein
8- [x] erweiterbar
9- [x] robust
10- [x] einfachst mögliche Lizenz
11
12Kurz: suckless!
13
14## Schnellstart für Ungeduldige
15
161\. Füge die beiden Dateien [csv.c](csv.c) und [csv.h](csv.h) Deinem C/C++ Projekt hinzu.
17
182\. Inkludiere die Headerdatei `csv.h`.
19
20~~~
21#include "csv.h"
22~~~
23
243\. Erstelle und initialisiere ein CSV-Objekt.
25
26~~~
27csv_t csv = { 0 }; oder csv_t csv;
28 csv_init(&csv);
29~~~
30
314\. Verarbeite die CSV-Datei
32
33~~~
34for ( int nf; (nf = csv_read(&csv, in)) != EOF; ) { /* eine Zeile aus `in` lesen */
35 for ( int i = 0; i < nf; i++ ) { /* `nf` beinhaltet die Feldanzahl */
36 const char *s = csv_field(&csv, i); /* jedes Feld der Zeile ansprechen */
37 /* ... */
38 }
39}
40~~~
41
42Es 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_field()` liefert einen (read only) `const char`-Zeiger für das i-te Feld.
45
46Der Speicher für das CSV-Objekt wird automatisch von `csv_read()` beim ersten Aufruf alloziert und wieder freigeben wenn der Stream `in` vollständig gelesen wurde.
47
48## Motivation
49
50Die meisten anderen CSV-Bibliotheken passen nicht:
51
52- falsche Verarbeitung bei eingeklammerten Feldern:
53 C++: `getline()` -> `stringstream` -> `getline()`;
54 C: `fgets()` -> `strtok`()
55- fehlerhafte Verarbeitung von "problematischen" CSV-Dateien (Linebreaks innerhalb einer Zelle)
56- unvorteilhafte Lizenz (GPL)
57- umständliche API (Callbacks zum Verarbeiten der Inhalte, seltsames Handling am Dateiende)
58- globale Variablen, die den Einsatz in Multi-Threadumgebungen unmöglich machen
59- C++ wenn ich C brauche
60- Java/Python/Rust/Ruby/${YourLanguageHere} wenn ich C brauche
61- Langsam, Aufgebläht
62- schlecht oder gar nicht anpassbar
63
64=> Selber schreiben!
65
66## Tutorial
67
68to be written
69
70## API
71
72### Typen
73
74**Fehlercodes** für die Callbackhandler:
75
76~~~
77typedef enum {
78 CSV_ERR_OK = 0,
79 CSV_ERR_OUT_OF_MEMORY = -1,
80 CSV_ERR_OUT_OF_RANGE = -2,
81 CSV_ERR_IO_READ = -3,
82 CSV_ERR_IO_WRITE = -4
83} csv_err_t;
84~~~
85
86**Optionen** für das Parsen eines CSV-Streams:
87
88~~~
89typedef struct {
90 int field_delimiter;
91 int field_separator;
92
93 void (*cb_error)(csv_err_t, void *);
94 void *cb_error_arg;
95
96 void *(*cb_allocate)(size_t, size_t, void *);
97 void *(*cb_reallocate)(void *, size_t, size_t, void *);
98 void (*cb_free)(void *, size_t, size_t, void *);
99 void *cb_memory_arg;
100} csv_options_t;
101
102extern const csv_options_t csv_default_options;
103~~~
104
105**Contextobjekt** zur Aufnahme der aktuell gelesenen Zeile:
106
107~~~
108typedef struct {
109 csv_options_t *csv_options;
110 /* additional internal fields */
111} csv_t;
112
113~~~
114
115### Funktionen
116
117**Initialisieren**
118
119~~~
120void csv_init(csv_t *csv);
121void csv_init_opt(csv_t *csv, const csv_options_t * const csv_options);
122~~~
123
124**Manuelles Freigeben**
125
126~~~
127void csv_cleanup(csv_t *csv);
128~~~
129
130**Zeilenweises Lesen**
131
132~~~
133int csv_read(csv_t *csv, FILE *in);
134~~~
135
136**Feldzugriff**
137
138~~~
139int csv_nfields(const csv_t * const csv);
140const char * csv_field(const csv_t * const csv, int idx);
141~~~
142
143**Fehlercodes als Textmeldung**
144
145~~~
146const char * csv_err_str(csv_err_t csv_err);
147~~~
148
149## Fehlerbehandlung
150
151to be written
152
153## Anpassungen
154
155Die CSV-Bibliothek kann an verschiedene Bedürfnisse angepasst werden.
156
157### Übersetzungsoptionen
158
159Beim Compilieren der Datei csv.c können die Standardwerte für Feldbegrenzer und Feldtrenner als Makrodefinitionen `CSV_DEFAULT_DELIMITER` und `CSV_DEFAULT_SEPARATOR` voreingestellt werden.
160
161Option Beschreibung Standardwert
162-------------------------- -------------- ---------------------------------
163`CSV_DEFAULT_DELIMITER` Feldbegrenzer `"`
164`CSV_DEFAULT_SEPARATOR` Feldtrenner `,`
165-------------------------- -------------- ---------------------------------
166Table: Makros
167
168Soll beispielsweise das in Deutschland viel häufiger vorkommende Semikolon (`;`) statt einem Komma (`,`) als Trennsymbol zwischen den Feldern einer CSV-Datei benutzt werden sieht der Aufruf zum Compilieren so aus:
169
170~~~
171cc -DCSV_DEFAULT_SEPARATOR="';'" -o csv-german.o -c csv.c
172~~~
173
174Anschließend wird die Datei `csv-german.o` statt `csv.o` zum Projekt dazugelinkt.
175
176Die Headerdatei (`csv.h`) bleibt unverändert.
177
178### Eigener Speicherallozierer
179
180to be written
181
182## Performance
183
184to be written
185
186## Lizenz
187
188In 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.
189
190Aus diesem Grund stelle ich meine Software (sofern nicht anders angegeben) unter der freizügigen [Do What the Fuck You Want to Public License](http://www.wtfpl.net) zur Verfügung. Vielleicht findet jemand den Code nützlich oder kann Erkenntnisse daraus gewinnen.
191
192~~~
193Copyright © 2020 Thomas Schmucker
194This work is free. You can redistribute it and/or modify it under the
195terms of the Do What The Fuck You Want To Public License, Version 2,
196as published by Sam Hocevar. See https://www.wtfpl.net/ for more details.
197~~~
198