Kiste
EN

Standard-Bibliothek — `csv`

Verfügbar — implementiert in Phase B.7.5. Vollständige Spec in docs/csv.md.

CSV (Comma-Separated Values) ist das Standard-Format für tabellarische Daten: Spreadsheet-Exporte, Datenbank-Dumps, Reports, Logs. Mit csv kannst du diese Daten lesen und schreiben.

27.1 Lesen — zwei Varianten

csv.zeilen(text) liefert eine rohe Tabelle (Liste von Listen):

nutze csv

nimm tabelle = csv.zeilen("name,alter\nBob,42\nEve,30")
sag tabelle
// [["name", "alter"], ["Bob", "42"], ["Eve", "30"]]

sag tabelle[1][0]              // "Bob"  (zweite Zeile, erste Spalte)

csv.karten(text) nutzt die erste Zeile als Header und gibt eine Liste von Karten zurück:

nimm leute = csv.karten("name,alter\nBob,42\nEve,30")
sag leute[0]["name"]           // "Bob"
sag leute[1]["alter"]          // "30"  (text, nicht ganz!)

27.2 Werte sind immer text

CSV hat keine Type-Information. Deshalb gibt Kiste bei csv.zeilen und csv.karten jede Zelle als text zurück — niemals automatisch als Zahl:

nimm zeile = csv.karten("alter,plz\n42,8000")[0]
sag zeile["alter"]              // "42"      (text!)
sag als_ganz(zeile["alter"])    // 42        (jetzt ganz)
sag zeile["plz"]                // "8000"    (text — bleibt so!)

Warum kein Auto-Parsing? „0123" (Postleitzahl) würde sonst zu 123 (führende Null verloren). „01.05" (Schweizer Datum) würde zu 1.05 (Zahl). Kiste vertraut dir, dass du weisst, welche Spalte was ist.

27.3 Schreiben

csv.erzeugt(zeilen) aus einer Liste von Listen:

nimm zeilen = [
    ["name", "alter"],
    ["Bob", "42"],
    ["Eve", "30"]
]
sag csv.erzeugt(zeilen)
// "name,alter\nBob,42\nEve,30\n"

Sonderzeichen werden automatisch gequotet:

sag csv.erzeugt([["a,b", "c\"d", "e\nf"]])
// "a,b","c""d","e
// f"

csv.erzeugt_aus_karten(karten) — Header wird automatisch aus den Schlüsseln der ersten Karte erzeugt:

nimm personen = [
    {"name": "Bob", "alter": 42},
    {"name": "Eve", "alter": 30}
]
sag csv.erzeugt_aus_karten(personen)
// "name,alter\nBob,42\nEve,30\n"

Alle Karten müssen die gleichen Schlüssel haben. Fehlende oder zusätzliche Schlüssel → Fehler. Das verhindert subtile Bugs durch stille Auffüllung.

27.4 Optionen — Trenner, Kommentare

Schweizer/deutsches Excel exportiert oft mit Semikolon. Dann gibst du eine Optionen-Karte mit:

nimm tabelle = csv.zeilen(text, {"trenner": ";"})

nimm mit_kommentaren = csv.zeilen(text, {
    "trenner": ";",
    "kommentar": "#"
})

Beim Schreiben ähnlich:

sag csv.erzeugt(zeilen, {"trenner": ";", "crlf_zeilenumbrüche": wahr})
// Windows-Excel-kompatibel mit CRLF und Semikolon
Option Wo Default Beschreibung
trenner lesen + schreiben "," Spalten-Trennzeichen, ein Grapheme
kommentar lesen nichts Zeilen die mit diesem Zeichen beginnen ignorieren
behalte_leere_zeilen lesen falsch leere Zeilen standardmäßig überspringen
crlf_zeilenumbrüche schreiben falsch \r\n statt \n

27.5 Praxis: Datei lesen, verarbeiten, schreiben

nutze csv
nutze datei

// Datei einlesen, als Karten parsen (setzt eine vorhandene Datei voraus):
nimm leute = csv.karten(datei.inhalt("personen.csv"))

// Filtern (alle über 30):
nimm erwachsene = liste.gefiltert(leute, funktion(p) {
    gib als_ganz(p["alter"]) > 30
})

// Zurückschreiben:
datei.schreibe("erwachsene.csv", csv.erzeugt_aus_karten(erwachsene))

27.6 Was nicht in csv v1 ist

  • Auto-Type-Detection — bewusst nicht (siehe §27.2).
  • Custom Quote-Char (' statt ") — RFC 4180 schreibt " vor.
  • Lazy-Quotes (kaputtes CSV trotzdem parsen) — Quelle von Daten-Korruption.
  • Streaming für riesige Dateien — kommt mit bytes/Streaming.
  • Excel-Spezifika wie BOM-Handling, Formel-Auswertung — csv ist Format-Layer.