2012-06-19 66 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