Dateien lesen und schreiben
let () =
let datei = Filename.temp_file "ocaml" ".txt" in
let oc = open_out datei in
output_string oc "eins\nzwei\ndrei\n";
Printf.fprintf oc "Zahl: %d\n" 42;
close_out oc;
let ic = open_in datei in
(try
while true do
let zeile = input_line ic in
Printf.printf "> %s\n" zeile
done
with End_of_file -> close_in ic);
(* mit Hilfsfunktion, die die Datei zuverlässig schließt *)
let alle_zeilen pfad =
let ic = open_in pfad in
Fun.protect ~finally:(fun () -> close_in ic) (fun () ->
let rec lies acc = match input_line ic with
| z -> lies (z :: acc)
| exception End_of_file -> List.rev acc in
lies [])
in
Printf.printf "%d Zeilen\n" (List.length (alle_zeilen datei));
Sys.remove datei;
Printf.printf "%b\n" (Sys.file_exists datei)Ausgabe
> eins > zwei > drei > Zahl: 42 4 Zeilen false
Kommandozeile und Umgebung
let () =
Printf.printf "Argumente: %d\n" (Array.length Sys.argv - 1);
(match Sys.getenv_opt "NICHT_GESETZT_XYZ" with
| Some v -> print_endline v
| None -> print_endline "Variable fehlt");
Printf.printf "%b\n" (Sys.os_type = "Unix");
Printf.printf "%d\n" Sys.word_sizeAusgabe
Argumente: 0 Variable fehlt true 64
Formatierte Ausgabe mit Format
type person = { name : string; alter : int }
let pp_person fmt p = Format.fprintf fmt "{ name = %s; alter = %d }" p.name p.alter
let () =
Format.printf "%a@." pp_person { name = "Mia"; alter = 17 };
Format.printf "@[<v>Zeile 1@,Zeile 2@]@.";
let s = Format.asprintf "%d-%s" 7 "x" in
print_endline s;
Printf.printf "%s\n" (Printf.sprintf "%08.3f" 3.14159)Ausgabe
{ name = Mia; alter = 17 }
Zeile 1
Zeile 2
7-x
0003.142Dune und Pakete
Echte Projekte nutzen dune:
(* dune-project *)
(lang dune 3.0)
(* bin/dune *)
(executable (name main) (libraries str))
(* bin/main.ml *)
let () = print_endline "Hallo aus dune"opam switch create 5.2.0 # Compiler installieren
opam install dune utop ocaml-lsp-server ocamlformat
dune build # bauen
dune exec ./bin/main.exe # starten
dune test # Tests ausführen
dune fmt # mit ocamlformat formatieren| Bibliothek | Zweck |
|---|---|
| Base/Core (Jane Street) | Alternative Standardbibliothek |
| Lwt, Async, Eio | Nebenläufigkeit und asynchrone I/O |
| Alcotest, OUnit | Tests |
| Cmdliner | Kommandozeilen-Parser |
| Yojson | JSON |
| Menhir, ocamllex | Parser-Generatoren |
| Dream | Webframework |
Tests schreiben
let assert_gleich name erwartet erhalten =
if erwartet = erhalten then Printf.printf "ok %s\n" name
else Printf.printf "FAIL %s\n" name
let rec fak n = if n <= 1 then 1 else n * fak (n - 1)
let () =
assert_gleich "fak 5" 120 (fak 5);
assert_gleich "fak 0" 1 (fak 0);
assert_gleich "liste" [2; 4] (List.map (fun x -> x * 2) [1; 2]);
assert (fak 3 = 6);
print_endline "alle Tests laufen"Ausgabe
ok fak 5 ok fak 0 ok liste alle Tests laufen
Merke
- Dateien:
open_in/open_out,input_line,Fun.protectzum sicheren Schließen Formatfür hübsche Ausgabe,Printf.sprintffür formatierte Strings- Projekte baut man mit dune und installiert Pakete mit opam
- Tests: Alcotest oder OUnit;
assertfür schnelle Prüfungen
Aufgabe
Lies eine Textdatei und gib die Zeilenanzahl und die längste Zeile aus.