Browse thread
[Caml-list] Better option to read a file
[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ 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