Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] Better option to read a file
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Christoph Bauer <c_bauer@i...>
Subject: Re: [Caml-list] Better option to read a file
Hi Agustín,

I'm not quite sure, what you want.  `leer' reads a whole file (this
whitout a upper limit on `long' a bad idea), `unir' doesn't work and
`leer2' is `read the first line of file and don't close the file'.
(Do you mean `let leer2 = input_line'?)

Because of `leer2', I assume you have a parser operating on lines.  As
Pietro I suggest the use of streams. A slightly more general approach
could improve the reuse of your code.


A file is a stream of chars but mostly you want to access whole lines
or words. Therefore we write this three functions:


let splitted_stream ~on_words char_stream = 
  let buf = Buffer.create 256 in
  let this_string () = 
    let str = Buffer.contents buf in
      Buffer.reset buf; str in
  let rec accumulate =
    parser 
	[< ''\n'; rest >] -> [< '(this_string ()); remove_cr rest >]
      | [< '' ' | '\t' as c; rest >] -> 
	  if on_words then [< '(this_string ()); accumulate rest >] 
	  else (
	    Buffer.add_char buf c;
	    accumulate rest
	  )
      | [< 'c; rest >] ->
	  Buffer.add_char buf c;
	  accumulate rest
      | [< >] -> [< >]
  and remove_cr = 
    parser 
	[< ''\r'; rest >] -> accumulate rest
      | [< rest >] -> accumulate rest
  in accumulate char_stream


let line_stream = splitted_stream ~on_words:false
let word_stream = splitted_stream ~on_words:true


Please note, that the input Stream could be obtained by Stream.of_channel,
Stream.of_string or Stream.from. The next function should apply your parser.

let rec stream_map f =
  parser
      [< 'a; rest >] -> [< '(f a); iter f rest >]
    | [< >] -> [< >]


The functions so far should be put in a generic library.

Assummed your parser is a function

parse_line: string -> 'a

then you can get the desired 'a Stream with

  let astream = stream_map parse_line (line_stream (Stream.of_channel (open_in fl)))

Regards,
Christoph Bauer




> Hi
>
> In a program  I need to read the input data from a file and I have
> written several options. I want to obtain the string of characters
> from a text file and I don't know what is the better option. Among
> others, I have written the following:
>
> First option:
>
> let leer_file fl =
>       let form = ref "" in
>       let arch = open_in fl in
>       let long = in_channel_length arch in
>       form := String.create (long-1);
>       really_input arch (!form) 0 (long-1);
>       close_in arch;
>       !form;;
>
> Second:
>
> let rec unir c ac = unir ac^(Char.escaped c);;
>
> let leer2 fl =
>       let form = ref "" in
>       let c = ref '-' in
>       let arch = open_in fl in
>       (try
>         (while true do (c := input_char arch); (if !c != '\n' then
> (form := unir !c !form) else ()) done)
>       with End_of_file -> close_in arch);
>       !form;;
>
> I also have a parser to convert the string, could I to improve these
> functions merging them with the parser in some way?
>
> Thanks for your help
>
> Agustín Valverde
> Department of Applied Mathematics
> University of Malaga, Spain
>
> -------------------
> To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
> Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>

-- 
beginfig(1)u=3cm;draw fullcircle scaled 2u;x0=x1=y1=x2=y3=0;-y0=y2=x3=1u;
filldraw z0..{left}z1{left}..z2{curl 1}..z3..z0..cycle;def t(expr p)=fullcircle
scaled .25u shifted(0,p*u);enddef;unfill t(.5);fill t(-.5);endfig;bye

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners