title: How to easily read lines from stdin?
body: <p>Some time ago, I decided to solve a simple task on HackerRank but using OCaml and Core, in order to learn them. In one of the tasks, I'm supposed to read data from standard input:</p>
  
  <blockquote>
    <p>The first line contains an integer, denoting the number of entries
    in the phone book. Each of the subsequent lines describes an entry in
    the form of space-separated values on a single line. The first value
    is a friend's name, and the second value is an -digit phone number.</p>
    
    <p>After the lines of phone book entries, there are an unknown number of
    lines of queries. Each line (query) contains a to look up, and you
    must continue reading lines until there is no more input.</p>
  </blockquote>
  
  <p>The main issues:</p>
  
  <ul>
  <li>I don't know how many lines there will be</li>
  <li>Last line don't ends by newline, so I can't just read <code>scanf "%s\n"</code> until <code>End_of_file</code></li>
  </ul>
  
  <p>And my code became messy:</p>
  
  <pre><code>open Core.Std
  open Printf
  open Scanf
  
  
  let read_numbers n =
      let phone_book = String.Table.create () ~size:n in
  
      for i = 0 to (n - 1) do
          match In_channel.input_line stdin with
          | Some line -&gt; (
              match (String.split line ~on:' ') with
              | key :: data :: _ -&gt; Hashtbl.set phone_book ~key ~data
              | _ -&gt; failwith "This shouldn't happen"
          )
          | None -&gt; failwith "This shouldn't happen"
      done;
  
      phone_book
  
  
  let () =
      let rec loop phone_book =
          match In_channel.input_line stdin with
          | Some line -&gt; (
              let s = match Hashtbl.find phone_book line with
                  | Some number -&gt; sprintf "%s=%s" line number
                  | None -&gt; "Not found"
              in
              printf "%s\n%!" s;
              loop phone_book
          )
          | None -&gt; ()
      in
  
      match In_channel.input_line stdin with
      | Some n -&gt; (
          let phone_book = read_numbers (int_of_string n) in
          loop phone_book
      )
      | None -&gt; failwith "This shouldn't happen"
  </code></pre>
  
  <p>If I solve this task in Python, then code looks like this:</p>
  
  <pre><code>n = int(input())
  book = dict([tuple(input().split(' ')) for _ in range(n)])
  
  while True:
      try:
          name = input()
      except EOFError:
          break
      else:
          if name in book:
              print('{}={}'.format(name, book[name]))
          else:
              print('Not found')
  </code></pre>
  
  <p>This is shorter and clearer than the OCaml code. Any advice on how to improve my OCaml code? And there two important things: I don't want to abandon OCaml, I just want to learn it; second - I want to use Core because of the same reason.</p>