如何在ocaml中读取文件?
我有一个以下格式的输入文件:如何在ocaml中读取文件?,ocaml,Ocaml,我有一个以下格式的输入文件: q0;q1 a;b (q0,x);(q1;x) 我想列出以下三个清单: a = ["q0";"q1"]; b = ["a";"b"]; c = [("q0","x");("q1","y")]; 这是我的密码: let buf = Queue.create ();; let catfile filename = let rec print_all_lines in_chan = Queue.add (input_line in_chan) buf;
q0;q1
a;b
(q0,x);(q1;x)
我想列出以下三个清单:
a = ["q0";"q1"];
b = ["a";"b"];
c = [("q0","x");("q1","y")];
这是我的密码:
let buf = Queue.create ();;
let catfile filename =
let rec print_all_lines in_chan =
Queue.add (input_line in_chan) buf;
print_all_lines in_chan
in
let in_file = open_in filename in
try
print_all_lines in_file
with End_of_file -> close_in in_file;;
catfile "test.txt";;
let rec pvt_rec_split skipf rv str c i limit =
if (List.length rv < (limit - 1)) && (i < String.length str) then (
if String.contains_from str i c then
let o = String.index_from str i c in
pvt_rec_split skipf
(rv @ [ String.sub str i (o - i)])
str c
(skipf str c o)
limit;
else
rv @ [ String.sub str i ((String.length str) - i) ]
) else (
if i < String.length str then
rv @ [ String.sub str i ((String.length str) - i) ]
else
rv
);;
let split s c limit =
let rec pvt_skip_char s c i =
if (i >= String.length s ) then (
String.length s
) else (
if ((String.get s i) == c) then (
pvt_skip_char s c (i +1)
) else (
i
)
)
in
pvt_rec_split pvt_skip_char [] s c 0 limit ;;
let a = split (Queue.take buf) ';' 100;;
let b = split (Queue.take buf) ';' 100;;
let c = split (Queue.take buf) ';' 100;;
让buf=Queue.create();;
让catfile文件名=
让rec打印\u chan中的所有\u行=
Queue.add(input_line in_chan)buf;
打印\u chan中的所有\u行
在里面
let in_file=在文件名中打开
尝试
打印\u文件中的所有\u行
使用_文件的结束->在_文件中关闭_;;
catfile“test.txt”;;
让rec pvt_rec_分割skipf rv str c i限制=
如果(List.length rv<(limit-1))&(i=String.length s),则(
字符串长度s
)否则(
如果((String.get s i)==c),则(
pvt_跳过字符s c(i+1)
)否则(
我
)
)
在里面
pvt_rec_split pvt_skip_char[]s c 0 limit;;
设a=split(Queue.take buf);'100;;
设b=split(Queue.take buf)'100;;
设c=split(Queue.take buf)'100;;
基本上,split函数使用分隔符分割字符串并返回一个列表
因此,我能够正确地生成列表a和b
但是对于列表c,我得到一个类型字符串列表。实际上,我想要一个类型为('string*'string)的列表
我该怎么做 文件内容(注意括号内的逗号分隔)
Ocaml代码
let split_str separator s =
let list = ref [] in
let start = ref 0 in
let () = try
while true do
let index = String.index_from s !start separator in
list := (String.sub s !start (index - !start)) :: !list;
start := index + 1
done
with Not_found -> list := (String.sub s !start ((String.length s) - !start)) :: !list
in List.rev !list;;
let maybe_input_line stdin =
try Some (input_line stdin) with
End_of_file -> None;;
let input_lines stdin =
let rec input lines =
match maybe_input_line stdin with
Some line -> input (line :: lines)
| None -> List.rev lines
in
input [];;
let rec parse_list_line delim line =
if (String.length line) > 0 then
let parts = split_str delim line in
parse_tokens parts
else
[]
and parse_tokens tokens =
let rec inner_parse_tokens buffer = function
[] -> List.rev buffer
| h :: t ->
let parsed = parse_line h in
inner_parse_tokens (parsed :: buffer) t
in
inner_parse_tokens [] tokens
and parse_line str =
if (String.length str) > 1 then
if str.[0] = '(' && str.[(String.length str) - 1] = ')' then
let substr = String.sub str 1 ((String.length str) - 2) in
split_str ',' substr
else
str :: []
else
str :: []
and parse_lines lines =
let rec inner_parse chunks = function
[] -> List.rev chunks
| head :: rest ->
let parsed = parse_list_line ';' head in
inner_parse (parsed :: chunks) rest
in
inner_parse [] lines;;
let file_channel = open_in("read_file2");;
let all_lines = input_lines file_channel;;
let chunks = parse_lines all_lines;;
let () = close_in file_channel;;
以及输出
# val file_channel : in_channel = <abstr>
# val all_lines : string list = ["q0;q1"; "a;b"; "(q0,x);(q1,x)"]
# val chunks : string list list list =
[[["q0"]; ["q1"]]; [["a"]; ["b"]]; [["q0"; "x"]; ["q1"; "x"]]]
#val文件_通道:在_通道中=
#val所有行:字符串列表=[“q0;q1”;“a;b”;(q0,x);(q1,x)]
#val块:字符串列表=
[q0];[q1”];[a”;[b”];[q0”;“x”;[q1”;“x”]]
请注意,在最后一次输出中,为了从ocaml函数返回相同的类型,我们必须使用单字符串项的列表。如果需要,您可以编写类似于matlab压缩函数的内容,将模块中的基本IO函数更改为
[[“q0”];[“q1”]
。例如,您可以使用read\u line
读取一行。我认为,你必须展示你已经试图获得更好建议的东西。(q0,x);(q1;x)
-您键入了一次,
和另一次代码>作为括号中示例输入中的分隔符
# val file_channel : in_channel = <abstr>
# val all_lines : string list = ["q0;q1"; "a;b"; "(q0,x);(q1,x)"]
# val chunks : string list list list =
[[["q0"]; ["q1"]]; [["a"]; ["b"]]; [["q0"; "x"]; ["q1"; "x"]]]