Home > Enterprise >  Reading integers from file Ocaml
Reading integers from file Ocaml

Time:05-05

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
  • Related