2016-03-30 11 views
0

Grundsätzlich habe ich eine Liste von Caches und ein Cache ist ein benutzerdefinierter Typ mit 16 Parametern. Mit meinem Code ich nur aus einer vorhandenen Datei den ersten Cache lesen, der existiert, wie lese ich rekursiv alle Caches in der Datei?Laden Sie eine Datei in Ocaml rekursiv

Der Cache ist bereits fertig gelesen werden:

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 
    } 
;; 

Und das ist, was im lesen (nicht recusive noch) nicht zu tun versuchen:

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 
;; 

Und falls Sie müssen testen es im heren den Cache-Typen setzen, so dass Sie es nicht schaffen müssen:

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  
} ;; 

Eine letzte Sache, zu testen und sehen, ob dies ist nur Arbeits den vollständigen Pfad ein, in dem die Datei:

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

Nun, es ist immer eine Freude zu antworten und keine Rückmeldung zu haben ;-) – Lhooq

Antwort

0

Wenn Sie schreiben:

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

Sie könnten stattdessen schreiben:

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 

Und Sie haben eine schöne Liste von Cache (nicht leer);)

Übrigens, in einem Datensatz, sagen wir

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

wenn Sie

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

schreiben, da Ihr Feldnamen 'a' und 'b' sind, können Sie

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

schreiben und OCaml wird es richtig füllen. ;)