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.

std.string · Exit-Codes · 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 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 (→ Exit-Codes).


Zahlen als Text

 
FloatToStr gibt für die meisten Werte eine falsche Zahl aus — nicht ungenau, sondern falsch (#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 (#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. </box> —- ===== 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 (#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: std.string — StrConcat, IntToStr, StrToInt · std.fs — Dateien lesen und schreiben · Exit-Codes · 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 (#1430), PrintfCore schreibt in ein String-Literal und ist fälschlich pub (#1431). Geprüft mit lyxc 1.0.21A.