這是我到目前爲止。這不是你需要的嗎?我不斷收到錯誤「錯誤:未綁定模塊標準」如何從OCaml中的文本文件讀取行?
let r file =
let chan = open_in file in
Std.input_list (chan)
這是我到目前爲止。這不是你需要的嗎?我不斷收到錯誤「錯誤:未綁定模塊標準」如何從OCaml中的文本文件讀取行?
let r file =
let chan = open_in file in
Std.input_list (chan)
如果您沒有安裝Extlib(顯然你不基於上述錯誤信息)做的話,一般它的完成是這樣的:
let read_file filename =
let lines = ref [] in
let chan = open_in filename in
try
while true; do
lines := input_line chan :: !lines
done; !lines
with End_of_file ->
close_in chan;
List.rev !lines ;;
如果你確實有EXTLIB:
let read_file filename =
let chan = open_in filename in
Std.input_list chan
...這是相當多的,你有什麼。
如果你有Batteries-included庫,你可以讀入文件到Enum.t和迭代,如下所示:
let filelines = File.lines_of filename in
Enum.iter (fun line -> (*Do something with line here*)) filelines
Std.input_list
顯然需要Extlib,你應該安裝系統(libextlib-ocaml
和libextlib-ocaml-dev
上在Debian系統上)。
下面是使用scanf函數的遞歸解決方案:
let read_all_lines file_name =
let in_channel = open_in file_name in
let rec read_recursive lines =
try
Scanf.fscanf in_channel "%[^\r\n]\n" (fun x -> read_recursive (x :: lines))
with
End_of_file ->
lines in
let lines = read_recursive [] in
let _ = close_in_noerr in_channel in
List.rev (lines);;
用法:
let all_lines = read_all_lines "input.txt";;
不過,我寧願流線由行:
let make_reader file_name =
let in_channel = open_in file_name in
let closed = ref false in
let read_next_line = fun() ->
if !closed then
None
else
try
Some (Scanf.fscanf in_channel "%[^\r\n]\n" (fun x -> x))
with
End_of_file ->
let _ = close_in_noerr in_channel in
let _ = closed := true in
None in
read_next_line;;
用法:
let read_next = make_reader "input.txt";;
let next_line = read_next();;
而且可能有點結冰:
type reader = {read_next : unit -> string option};;
let make_reader file_name =
let in_channel = open_in file_name in
let closed = ref false in
let read_next_line = fun() ->
if !closed then
None
else
try
Some (Scanf.fscanf in_channel "%[^\r\n]\n" (fun x -> x))
with
End_of_file ->
let _ = close_in_noerr in_channel in
let _ = closed := true in
None in
{read_next = read_next_line};;
用法:
let r = make_reader "input.txt";;
let next_line = r.read_next();;
希望這有助於!
[http://caml.inria.fr/pub/docs/manual-ocaml/libref/Scanf.html#space](http://caml.inria.fr/pub/docs/manual-ocaml/libref/Scanf .html#space) _ ** ...類似地,格式字符串中的換行符匹配單個換行或回車後跟換行** _ 因此,此解決方案「應該」適用於「\ r \ n」和「\ n」樣式行結尾(僅在Linux系統上測試)。 – 2012-11-10 14:22:31
所有代碼片段都不關閉輸入通道,因此泄漏文件描述符 – ygrek 2012-11-21 16:09:50
@ygrek:謝謝!固定。可能最好讓主叫方開啓/關閉業務,並讓這些功能代替輸入頻道。 – 2012-11-21 16:47:45
使用Scanf「字符串指示」和零寬度字符從文件中讀取行的另一種樣式。這就像傳統的祈禱風格。
open Scanf
open Printf
(* little helper functions *)
let id x = x
let const x = fun _ -> x
let read_line file = fscanf file "%[email protected]\n" id
let is_eof file = try fscanf file "%0c" (const false) with End_of_file -> true
let _ =
let file = open_in "/path/to/file" in
while not (is_eof file) do
let s = read_line file in
(* do something with s *)
printf "%s\n" s
done;
close_in file
注:
如果您已經安裝了OCaml的核心庫,那麼很簡單:
open Core.Std
let r file = In_channel.read_lines file
如果您已經安裝corebuild
,那麼你可以用它編譯代碼:
corebuild filename.byte
如果您的代碼駐留在名爲filename.ml
的文件中。
如果您沒有OCaml Core,或者不想安裝它或其他標準庫實現,那麼您當然可以使用vanilla OCaml的標準庫來實現它。在Pervasives
模塊中定義了一個函數input_line
,該函數在所有OCaml程序中自動打開(即,所有的定義都可以在沒有進一步說明的情況下使用模塊名稱進行訪問)。該函數接受in_channel
類型的值並返回從通道讀取的一行。使用此功能,可以實現所需的功能:
let read_lines name : string list =
let ic = open_in name in
let try_read() =
try Some (input_line ic) with End_of_file -> None in
let rec loop acc = match try_read() with
| Some s -> loop (s :: acc)
| None -> close_in ic; List.rev acc in
loop []
此實現使用遞歸,並且更加自然的OCaml節目。
這讀取文件的線,並打印它們:
open Core.Std
let handle_line line =
printf "Your line: %s \n" line
let() =
let file_to_read = "./file_to_read.txt" in
let lines = In_channel.read_lines file_to_read in
List.iter ~f: handle_line lines
這裏是不累積的線條或使用外部庫,一個簡單的遞歸的解決方案,但可讓您閱讀使用有一條線,工藝函數,遞歸地讀取下一個,直到完成,然後乾淨地退出。 exit函數關閉打開的文件句柄,並向調用程序發出成功信號。
let read_lines file process =
let in_ch = open_in file in
let rec read_line() =
let line = try input_line in_ch with End_of_file -> exit 0
in (* process line in this block, then read the next line *)
process line;
read_line();
in read_line();;
read_lines some_file print_endline;;
非常感謝! – Travis 2011-04-25 20:12:05
在extlib變體中檢測到fd泄漏:輸入通道未關閉 – ygrek 2012-11-21 16:08:27
您能解釋爲什麼您將while循環鏈接爲空列表?我認爲它永遠不會達成。 – Rizo 2015-05-08 16:32:31