2012-06-19 67 views
1

我有以下格式的输入文件:如何从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; 
    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;; 

基本上拆分功能拆分带分隔符的字符串并返回一个列表。

所以,我能够正确生成列表a和b。

但是在List c的情况下,我得到一个类型字符串列表。其实我想要一个带有类型('string *'字符串)的列表。

我该怎么做?

+1

基本IO功能在[Pervasives](http://caml.inria.fr/pub/docs/manual-ocaml /libref/Pervasives.html)模块。例如,您可以用'read_line'来读取一行。我想,你必须展示你已经试图获得更好的建议。 –

回答

2

文件的内容(括号内通知逗号分离)

q0;q1 
a;b 
(q0,x);(q1,x) 

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"]]] 

请,通知,在最后的输出,我们有为单个字符串项目使用列表以便从ocaml函数返回相同类型。如果你愿意,你可以写类似的东西把MATLAB 挤压功能改变[["q0"]; ["q1"]]["q0"; "q1"]

+0

'(q0,x);(q1; x)' - 您在括号中输入了一次''''和其他时间';'作为示例输入中的分隔符 – Ribtoks

+0

@ user1280282我已更新答案 – Ribtoks