2016-03-30 18 views
0

基本的に私はキャッシュのリストを持っており、キャッシュは16のパラメータを持つユーザ定義タイプです。私のコードでは、既存のファイルから既存の最初のキャッシュを読み取るだけですが、ファイル内のすべてのキャッシュを再帰的に読み取るにはどうすればよいですか?ocamlの再帰的な方法でファイルをロードする

キャッシュがすでに読み込み可能:

let loadCache ci = 
    let code = input_line ci in 
    let name = input_line ci in 
    let state = input_line ci in 
    let owner = input_line ci in 
    let latitude = float_of_string (input_line ci) in 
    let longitude = float_of_string (input_line ci) in 
    let kind = input_line ci in 
    let size = input_line ci in 
    let difficulty = float_of_string (input_line ci) in 
    let terrain = float_of_string (input_line ci) in 
    let status = input_line ci in 
    let hiddenDate = input_line ci in 
    let nFounds = int_of_string (input_line ci) in 
    let nNotFounds = int_of_string (input_line ci) in 
    let nFavourites = int_of_string (input_line ci) in 
    let altitude = int_of_string (input_line ci) in { 
     code = code; name = name; state = state; owner = owner; 
     latitude = latitude; longitude = longitude; 
     kind = kind; size = size; difficulty = difficulty; terrain = terrain; 
     status = status; hiddenDate = hiddenDate; 
     nFounds = nFounds; nNotFounds = nNotFounds; nFavourites = nFavourites; 
     altitude = altitude 
    } 
;; 

そして、これは(まだrecusiveない)読むことをやろうとして何イムです:

val load: string -> cache list 

let rec loadChannel ci = 
    try 
    loadCache ci 
    with End_of_file -> raise (Arg.Bad "loadChannel: no caches on this file to read")  
;; 

let load filename = (* post: result is never [] *) 
let ci = open_in filename in 
    let cl = loadChannel ci in 
     close_in ci; cl 
;; 

そして場合には、あなたがテストする必要がありますここにキャッシュタイプを入れて、それを作成する必要はありません:

type cache = {   
    code: string;  
    name: string;  
    state: string;  
    owner: string;  
    longitude: float; 
    kind: string;  
    size: string;  
    difficulty: float; 
    terrain: float;  
    status: string;  
    hiddenDate: string; 
    nFounds: int;  
    nNotFounds: int;  
    nFavourites: int; 
    altitude: int  
} ;; 

これは最後のことですか?あなたが書くとき

let q = load "C: ...... file.txt" 
+2

まあ、いつも答えて、フィードバックはありません;-) – Lhooq

答えて

0

let rec loadChannel ci = 
    try 
    loadCache ci 
    with End_of_file -> raise (Arg.Bad "loadChannel: no caches on this file to read")  

をあなたが代わりに書くことができる:(

let loadCache ci = 
    let code = try Some (input_line ci) with End_of_file -> None in 
    match code with 
    | None -> raise Exit 
    | Some code -> 
    try 
     let name = input_line ci in 
     let state = input_line ci in 
     let owner = input_line ci in 
     let latitude = float_of_string (input_line ci) in 
     let longitude = float_of_string (input_line ci) in 
     let kind = input_line ci in 
     let size = input_line ci in 
     let difficulty = float_of_string (input_line ci) in 
     let terrain = float_of_string (input_line ci) in 
     let status = input_line ci in 
     let hiddenDate = input_line ci in 
     let nFounds = int_of_string (input_line ci) in 
     let nNotFounds = int_of_string (input_line ci) in 
     let nFavourites = int_of_string (input_line ci) in 
     let altitude = int_of_string (input_line ci) in 
     { 
      code; name; state; owner; latitude; longitude; 
      kind; size; difficulty; terrain; status; hiddenDate; 
      nFounds; nNotFounds; nFavourites; altitude 
     } 
    with End_of_file -> raise (Arg.Bad "loadChannel: no caches on this file to read or not enough informations") 

let rec loadChannel ci acc = 
    try 
    let c = loadCache ci in 
    loadChannel ci (c::acc) 
    with Exit -> acc (* If we have an Exit, it means that the first read 
         was an End_of_file so it's not a mistake, just 
         a proper End_of_file. If this exception appears 
         after, it means that we were reading a cache and 
         couldn't finish the reading. *) 

let load filename = (* post: result is never [] *) 
    let ci = open_in filename in 
    let cl = loadChannel ci in 
    close_in ci; 
    match cl with 
     | [] -> raise BIGEXCEPTION 
     | _ -> cl 

をそして、あなたはキャッシュの素敵なリストを持っているだけで、ファイルがある完全なパスを入力する作業空ではない);)

ところで、レコードでは、

type r = {a : int; b : int} 

あなたは

let a = 3 and b = 4 in {a = a; b = b} 

を書く場合、あなたのフィールド名は 'a' と 'b' であるため、あなたは

let a = 3 and b = 4 in {a; b} 

とOCamlのを書くことができますが、それを正しく記入します。 ;)

関連する問題