I have to read integers from a "file.txt" in ocaml and store them in a list. I have tried to read with stdlib but it does not work. Also i cannot understand how scanf works for files. If someone could help me with scanf i would be grateful.
Edit Sorry for not being clear enough, first time posting. The input format is a b c\n d e f\n ... Yes it is for my university. Basically i have to find mst of a graph. The input is vertex_1 vertex_2 weight \n and so on and i am trying to build a list of tuples [(vertex_1 vertex_2 weight),...] from input. In my code i am trying to gather chars to a string if its needed (ex two digit numbers) and then converting string to int. But i hope there is an easier way of doing that. I have to say that is the second day that i am programming in ocaml.
let entry_of_channel ch =
let number = input_char ch in number
let rec list_of_channel ch =
try
let e = entry_of_channel ch in
e:: list_of_channel ch
with
End_of_file -> []
let string_of_chars chars =
let buf = Buffer.create 16 in
List.iter(Buffer.add_char buf) chars
let rec list_clear list buffer =
match list with
[] -> []
|' '::t -> (string_of_chars buffer)::list_clear t []
|'\n'::t ->(string_of_chars buffer)::list_clear t []
|h::t -> buffer @ h;
list_clear t buffer
let graph filename =
let ch = open_in filename in
let l = list_of_channel ch in
close_in ch;
let l_new = list_clear l [] in
l_new
CodePudding user response:
Since this is presumably for a school assignment, you should ideally show some code you've written and ask for help with a specific problem. However, reading integers from a file is probably not the interesting part of the assignment.
You don't give any information about the format of the file. Here's a function that reads whatever integers it finds on lines in a file, separated by spaces and tabs:
let read_ints filename =
let inchan = open_in filename in
let spre = Str.regexp "[ \t] " in
let rec loop accum =
match input_line inchan with
| line ->
let wds = Str.split spre line in
loop (List.rev (List.map int_of_string wds) @ accum)
| exception End_of_file ->
close_in inchan;
List.rev accum
in
loop []
Note that this does not handle errors. If the file can't be opened, or if there are non-integer values in the file, the code will raise an exception.
Here is a similar function that uses Scanf.fscanf
:
let read_ints filename =
let inchan = open_in filename in
let rec loop accum =
match Scanf.fscanf inchan " %d" Fun.id with
| n -> loop (n :: accum)
| exception End_of_file ->
close_in inchan;
List.rev accum
in
loop []
CodePudding user response:
Sorry for not being clear enough, first time posting. The input format is a b c\n d e f\n ... Yes it is for my university. Basically i have to find mst of a graph. The input is vertex_1 vertex_2 weight \n and so on and i am trying to build a list of tuples [(vertex_1 vertex_2 weight),...] from input. In my code i am trying to gather chars to a string if its needed (ex two digit numbers) and then converting string to int. But i hope there is an easier way of doing that. I have to say that is the second day that i am programming in ocaml.
let entry_of_channel ch =
let number = input_char ch in number
let rec list_of_channel ch =
try
let e = entry_of_channel ch in
e:: list_of_channel ch
with
End_of_file -> []
let string_of_chars chars =
let buf = Buffer.create 16 in
List.iter(Buffer.add_char buf) chars
let rec list_clear list buffer =
match list with
[] -> []
|' '::t -> (string_of_chars buffer)::list_clear t []
|'\n'::t ->(string_of_chars buffer)::list_clear t []
|h::t -> buffer @ h;
list_clear t buffer
let graph filename =
let ch = open_in filename in
let l = list_of_channel ch in
close_in ch;
let l_new = list_clear l [] in
l_new