2011-06-21 9 views
5

Próbuję napisać małe narzędzia, aby przyzwyczaić się do programowania Unix z OCaml. Oto moja próba dla cat:Pisanie kota w OCaml: użycie Unix.read

open Unix ;; 

    let buffer_size = 10 
    let buffer = String.create buffer_size 

    let rec cat = function 
     | [] ->() 
     | x :: xs -> 
     let descr = openfile x [O_RDONLY] 0 in 

     let rec loop() = 
      match read descr buffer 0 buffer_size with 
      | 0 ->() 
      | _ -> print_string buffer; loop() in 
     loop(); 
     print_newline(); 
     close descr; 
     cat xs ;; 


    handle_unix_error cat (List.tl (Array.to_list Sys.argv)) 

Wydaje się, że problemem jest to, że w ostatnim wywołaniu read bufor nie całkowicie wypełnić, ponieważ nie ma nic więcej do czytania, do końca co bufor uprzednio zawarte zostanie również wydrukowany. Przeczytałem kilka przykładowych kodów używając read i nie zdawało się, że używają one String.create za każdym razem, gdy uzupełniają bufor (który w każdym razie nadal wypełnia go pewnymi znakami ...); więc co powinienem zrobić? Dzięki.

Odpowiedz

4

Zwrot z Unix.read (który zignorowałeś, z wyjątkiem sprawdzenia dla 0), jest liczbą odczytanych znaków, więc powinieneś używać tylko wielu znaków bufora.

Ale naprawdę, po co zawracać sobie głowę niską zawartością Uniksa? Dlaczego nie używać zwykłych funkcji otwierania i odczytu plików OCaml?

+0

Czytam "Programowanie systemu Unix z Objective Caml", który mówi o tym module Unix. Czy powinienem tego unikać? – rochem

+1

@rochem To zależy od celów. Kurs ten da ci wiedzę na temat Uniksa, którą możesz przenieść na inne języki (podanie bufora i rozmiaru bufora, a otrzymanie liczby zwracanych znaków w zamian jest typową metodą w C). Ponieważ te połączenia tak ściśle odpowiadają wywołaniom C, prawie nigdy nie są używane w zwykłym programowaniu Caml, więc to, czego ten kurs nie nauczy, to jak pisać idiomatyczne programy OCaml. –