練習問題 10.3 fold コマンド

2008年4月15日
1 分

プログラミング in OCaml 関数型プログラミングの基礎からGUI構築までのp.215より。

wc コマンドはなんか難しいのでこっちを先に。

UNIX の fold コマンドは,ファイル名の列を引数として,その内容を,長い行を複数の短い 行(デフォルトでは80文字)に分割しながら表示します。これを OCaml で実装し,実行可能 ファイルを作成しなさい。オプションとしては,行の長さを整数で指定する --width を実装 しなさい。

let version = "0.1"
let filenames = ref []
let width = ref 80

let spec = [("--width",
             Arg.Int (fun n -> width := n),
             "Set line width");
            ("--version",
             Arg.Unit (fun () -> Printf.printf "fold in OCaml ver.%s\n" version),
             "Display version")]

let rec fold_line n str =
  let len = String.length str in
  if len > n then
    ( print_endline (String.sub str 0 n);
      fold_line n (String.sub str n (len - n)))
  else
    print_endline str

let rec each_line ic =
  fold_line !width (input_line ic);
  each_line ic

let fold_file filename =
  let infile = open_in filename in
  try
    each_line infile
  with
    End_of_file -> close_in infile

let () =
  Arg.parse spec
            (fun s -> filenames := s :: !filenames)
            "Usage: fold [--width width] [--help] [--version] filename ...";
  List.iter fold_file (List.rev !filenames)
^o^ >ocamlc -o fold.exe fold.ml

^o^ >fold --width 40 fold.ml
let version = "0.1"
let filenames = ref []
let width = ref 80

let spec = [("--width",
             Arg.Int (fun n -> width :=
n),
             "Set line width");
            ("--version",
              Arg.Unit (fun () -> Printf
.printf "fold in OCaml ver.%s\n" version
),
             "Display version")]

let rec fold_line n str =
  let len = String.length str in
  if len > n then
    ( print_endline (String.sub str 0 n)
;
(以下略)