====== std.io ======
Ergänzungen zur Konsolenausgabe: zeilenbrechende Varianten der Ausgabe-Builtins, Umwandlung von Wahrheitswerten und Fließkommazahlen in Text, formatierte Ausgabe über typisierte ''Printf…''-Funktionen und ein benannter Prozessabbruch.
→ [[lyx_-_programmiersprache:units:string|std.string]] · [[lyx_-_programmiersprache:sprache:exit-codes|Exit-Codes]] · [[lyx_-_programmiersprache:units|Standard Library]]
Alle Beispiele dieser Seite sind mit ''lyxc 1.0.21A'' übersetzt und ausgeführt; die gezeigten Ausgaben sind echte Programmausgaben.
> **Für die Grundausgabe braucht es diese Unit nicht.** ''Print'', ''PrintLn'', ''PrintStr'', ''PrintInt'', ''PrintFloat'', ''PrintBool'', ''PrintF64'' und ''IntToStr'' sind **Compiler-Builtins** und ohne jeden ''import'' verfügbar. Frühere Fassungen dieser Seite führten sie als Funktionen von ''std.io'' — das stimmt nicht; die Unit definiert nur ''Print'' als Hülle um das Builtin ''PrintStr''.
>
> ''StrToInt'' gehört ebenfalls nicht hierher, sondern zu [[lyx_-_programmiersprache:units:string|std.string]].
// Builtins: kein Import noetig
fn main(): int64 {
Print("ohne Zeilenumbruch, ");
PrintLn("mit Zeilenumbruch");
PrintInt(42); PrintLn("");
PrintF64(3.5);
PrintLn(StrConcat("Zahl als Text: ", IntToStr(42)));
return 0;
}
ohne Zeilenumbruch, mit Zeilenumbruch
42
3.500000
Zahl als Text: 42
----
===== Was die Unit beisteuert =====
^ Signatur ^ Beschreibung ^
| ''Print(s: pchar): void'' | Hülle um das Builtin ''PrintStr'' — ohne Zeilenumbruch |
| ''PrintStrLn(s: pchar): void'' | Text mit Zeilenumbruch |
| ''PrintIntLn(n: int64): void'' | Ganzzahl mit Zeilenumbruch |
| ''PrintFloatLn(x: f64): void'' | Fließkommazahl mit Zeilenumbruch (sechs Nachkommastellen) |
| ''PrintBoolLn(b: bool): void'' | ''true'' / ''false'' mit Zeilenumbruch |
| ''BoolToStr(b: bool): pchar'' | ''true'' / ''false'' als Text |
| ''FloatToStr(val: f64, prec: int64): pchar'' | Fließkommazahl mit gewählter Stellenzahl — **liefert falsche Werte, siehe Kasten** |
| ''ExitProc(code: int64): void'' | Namensalias für das Builtin ''exit()'' |
''PrintIntLn'' und ''PrintStrLn'' waren früher als Builtin registriert, aber in keinem Backend umgesetzt — der Aufruf bestand die Semantikprüfung und scheiterte erst im Codegen. Seither leben sie hier.
''ExitProc'' beendet den Prozess sofort; unter Linux zählen nur die unteren acht Bit des Codes (→ [[lyx_-_programmiersprache:sprache:exit-codes|Exit-Codes]]).
----
===== Zahlen als Text =====
> **''FloatToStr'' gibt für die meisten Werte eine falsche Zahl aus** — nicht ungenau, sondern falsch ([[https://github.com/SEOLizer/LyX-Compiler/issues/1430|#1430]]):
>
> ^ Aufruf ^ Ergebnis ^ richtig wäre ^
> | ''%%FloatToStr(5.02, 2)%%'' | ''5.1'' | ''5.02'' |
> | ''%%FloatToStr(1.05, 2)%%'' | ''1.4'' | ''1.05'' |
> | ''%%FloatToStr(0.07, 2)%%'' | ''0.6'' | ''0.07'' |
> | ''%%FloatToStr(7.001, 3)%%'' | ''7.0'' | ''7.001'' |
> | ''%%FloatToStr(12.3, 2)%%'' | ''12.29'' | ''12.30'' |
>
> Ursache: Der Nachkommateil wird als ganze Zahl gerechnet und **ohne führende Nullen** ausgegeben; zusätzlich wird abgeschnitten statt gerundet. Aus 5,02 € werden so 5,10 €, ohne dass irgendetwas auffällt.
>
> **Bis das behoben ist:** Für Geldbeträge in Festkomma rechnen (''int64'' × 100) und die Nachkommastellen selbst zusammensetzen. Für Anzeigezwecke ist das Builtin ''PrintF64'' die bessere Wahl — es gibt sechs Stellen aus und schneidet nur die letzte ab (''5.019999'' statt ''5.020000'').
Ein Wert und wachsende Stellenzahl zeigt das Muster:
FloatToStr(20.1, 1) -> 20.0 richtig: 20.1
FloatToStr(20.1, 2) -> 20.9 richtig: 20.10
FloatToStr(20.1, 3) -> 20.99 richtig: 20.100
Richtig behandelt werden dagegen die Sonderfälle: ''inf'' und ''nan'' liefern seit #1284 genau diese Wörter statt Zahlenmüll, und der Zielpuffer ist kein String-Literal mehr.
----
===== Formatierte Ausgabe =====
Lyx kennt keine variadischen Funktionen. Statt eines einzigen ''Printf'' gibt es deshalb **eine Funktion je Argumentmuster**, benannt nach den Typen: ''S'' für ''pchar'', ''I'' für ''int64'', ''F'' für ''f64'', ''B'' für ''bool''.
^ Argumente ^ Verfügbare Muster ^
| eines | ''PrintfS'', ''PrintfI'', ''PrintfF'', ''PrintfB'' |
| zwei | ''PrintfSS'', ''PrintfSI'', ''PrintfIS'', ''PrintfII'', ''PrintfIF'', ''PrintfFF'' |
| drei | ''PrintfSSS'', ''PrintfSIS'', ''PrintfISI'', ''PrintfIII'', ''PrintfFFF'' |
| vier | ''PrintfSSSS'', ''PrintfIIII'', ''PrintfISIF'' |
Alle liefern die Zahl der ausgegebenen Zeichen zurück.
^ Platzhalter ^ Bedeutung ^
| ''%s'' | nächstes Argument |
| ''%d'' | nächstes Argument |
| ''%f'' | nächstes Argument |
| ''%%%%'' | ein Prozentzeichen |
> **''%s'', ''%d'' und ''%f'' sind gleichwertig.** Die Umwandlung in Text erledigt die aufgerufene ''Printf…''-Variante anhand ihres Namens, bevor der Formatkern die Argumente sieht — dieser setzt sie nur noch der Reihe nach ein. Ein ''%d'' an der Stelle eines Textarguments ist also kein Fehler, sondern liefert denselben Text. Maßgeblich ist die **Reihenfolge**, nicht der Buchstabe.
>
> Ein **unbekannter Platzhalter** wird wörtlich ausgegeben: ''%q'' erscheint als ''%q''. Feldbreiten, Genauigkeit und Flags (''%5d'', ''%.2f'', ''%-10s'') gibt es nicht.
import std.io;
import std.string;
fn main(): int64 {
// Aus der Unit: Zeilenbrechende Varianten und Umwandlungen
PrintStrLn("PrintStrLn haengt den Umbruch an"c);
PrintIntLn(42);
PrintFloatLn(2.5);
PrintBoolLn(true);
PrintLn(StrConcat("BoolToStr(false): ", BoolToStr(false)));
// Formatierte Ausgabe: der Name nennt die Argumenttypen
var n: int64 := PrintfSI("Nutzer %s hat %d Punkte\n"c, "anna"c, 42);
PrintLn(StrConcat(" ausgegebene Zeichen: ", IntToStr(n)));
PrintfII("%d + %d\n"c, 2, 3);
PrintfS("Prozent: 100%% fertig\n"c, ""c);
PrintfS("Unbekannter Platzhalter: %q\n"c, "x"c);
return 0;
}
PrintStrLn haengt den Umbruch an
42
2.500000
true
BoolToStr(false): false
Nutzer anna hat 42 Punkte
ausgegebene Zeichen: 26
2 + 3
Prozent: 100% fertig
Unbekannter Platzhalter: %q
> **''__PrintfCore'' schreibt in ein String-Literal.** Der Formatkern gibt jedes Zeichen einzeln aus und benutzt dafür das Literal ''%%" "%%'' als Ein-Byte-Puffer — dieselbe Klasse, die in dieser Datei schon zweimal Fehler verursacht hat (#1259, #1260; in ''FloatToStr'' mit #1284 behoben). Heute geht es gut, weil der Datenbereich beschreibbar ist; sobald Literale schreibgeschützt liegen, stürzt jeder ''Printf…''-Aufruf ab ([[https://github.com/SEOLizer/LyX-Compiler/issues/1431|#1431]]).
>
> Nebenwirkung heute schon: ein Syscall je ausgegebenem Zeichen. Für größere Ausgaben ist ''StrConcat'' + ''PrintLn'' schneller.
>
> ''__PrintfCore'' ist zudem ''pub'' und taucht deshalb in der Schnittstelle auf, obwohl der Name sie als intern kennzeichnet.
----
===== Wann was =====
^ Aufgabe ^ Empfehlung ^
| Text ausgeben | ''PrintLn'' / ''Print'' (Builtins) |
| Zahl anhängen | ''%%StrConcat(text, IntToStr(n))%%'' |
| Fließkommazahl anzeigen | ''PrintF64'' (Builtin) — **nicht** ''FloatToStr'' |
| Geldbetrag ausgeben | Festkomma (''int64'' × 100) und Nachkommastellen selbst setzen |
| Zeile mit mehreren Werten | ''Printf…'' passend zur Argumentfolge |
| Viel Text am Stück | in einem Puffer sammeln, einmal ausgeben |
| Programm beenden | ''exit()'' (Builtin) oder ''ExitProc'' |
----
===== Fallstricke =====
* **''FloatToStr'' nicht für Zahlen verwenden, die stimmen müssen** ([[https://github.com/SEOLizer/LyX-Compiler/issues/1430|#1430]]).
* **''prec = 0'' liefert trotzdem einen Dezimalpunkt**: ''%%FloatToStr(2.5, 0)%%'' ergibt ''2.0''.
* **Der Name der ''Printf…''-Variante muss zur Argumentfolge passen** — es gibt keine Prüfung zur Übersetzungszeit, ob Formatstring und Argumentzahl zusammenpassen. Mehr Platzhalter als Argumente bleiben schlicht leer.
* **Keine Feldbreiten und keine Genauigkeit** in Formatstrings; für Ausrichtung selbst mit Leerzeichen auffüllen.
* **Nicht jedes Argumentmuster existiert.** Für Kombinationen außerhalb der Tabelle (etwa ''pchar'', ''f64'', ''pchar'') die Werte vorher in Text umwandeln und ''PrintfSSS'' nehmen.
* **''Print'' der Unit und ''Print'' des Compilers** tragen denselben Namen; nach ''import std.io'' ruft man die Hülle, ohne Import das Builtin. Verhalten ist identisch.
* **Keine Ausgabe auf stderr**, keine Pufferung, kein Zeilenumbruch-Handling für Windows — alles geht ungepuffert nach stdout.
----
**Weiterführend:** [[lyx_-_programmiersprache:units:string|std.string — StrConcat, IntToStr, StrToInt]] · [[lyx_-_programmiersprache:units:fs|std.fs — Dateien lesen und schreiben]] · [[lyx_-_programmiersprache:sprache:exit-codes|Exit-Codes]] · [[lyx_-_programmiersprache:units|Standard Library]]
**Quelle:** ''std/io.lyx'' (315 Zeilen) · **Autor:** Andreas Röne · **Copyright:** 2024–2025 Andreas Röne
Letzte Aktualisierung: 2026-08-13 — Seite gegen ''std/io.lyx'' überarbeitet. Die Funktionsliste nannte ''PrintStr'', ''PrintInt'', ''PrintFloat'', ''PrintBool'' und ''IntToStr'' als Bestandteile der Unit — es sind **Compiler-Builtins**; ''StrToInt'' gehört zu ''std.string''. Neu: zwei lauffähige Beispiele mit echter Ausgabe, Übersicht der ''Printf…''-Muster samt Platzhalter-Verhalten, Entscheidungstabelle, Fallstricke. Belegt und als Issue erfasst: ''FloatToStr'' liefert falsche Zahlen ([[https://github.com/SEOLizer/LyX-Compiler/issues/1430|#1430]]), ''__PrintfCore'' schreibt in ein String-Literal und ist fälschlich ''pub'' ([[https://github.com/SEOLizer/LyX-Compiler/issues/1431|#1431]]). Geprüft mit ''lyxc 1.0.21A''.