从字符串中读取整数

时间:2016-04-17 11:28:00

标签: string ocaml

我想从文件中读取一行,从该行初始化一个数组,然后显示整数。 为什么不读行中的五个整数?我想获得输出1 2 3 4 5,我有1 1 1 1 1

open Array;;
open Scanf;;

let print_ints file_name = 
  let file = open_in file_name in
  let s = input_line(file) in
  let n = ref 5 in
  let arr = Array.init !n (fun i -> if i < !n then sscanf s "%d" (fun a -> a) else 0) in
  let i = ref 0 in 
  while !i < !n do
    print_int (Array.get arr !i);
    print_string " ";
    i := !i + 1;
  done;;

print_ints "string_ints.txt";;

我的档案只是:1 2 3 4 5

1 个答案:

答案 0 :(得分:3)

您可能想尝试以下方法。将字符串拆分为表示数字的子字符串列表。 This answer描述了这样做的一种方式。然后在print_ints函数中使用结果函数。

let ints_of_string s = 
  List.map int_of_string (Str.split (Str.regexp " +") s)

let print_ints file_name = 
  let file = open_in file_name in
  let s = input_line file in
  let ints = ints_of_string s in
  List.iter (fun i -> print_int i; print_char ' ') ints;
  close_in file

let _ = print_ints "string_ints.txt"

编译时,将str.cmastr.cmxa作为参数传递(有关编译的详细信息,请参阅this answer):

$ ocamlc str.cma print_ints.ml

另一种选择是使用Scanf.bscanf函数 - this question,包含一个示例(请谨慎使用)。

Scanf.sscanf函数可能不是特别适合此任务。 摘自OCaml manual

  

scanf工具不适用于重型词法分析和解析。如果它看起来不足以满足您的需求,则存在几种替代方案:正则表达式(模块Str),流解析器,ocamllex生成的词法分析器,ocamlyacc生成的解析器

虽然有一种方法可以使用Scanf.sscanf解析一串整数(我不推荐):

let rec int_list_of_string s =
  try
    Scanf.sscanf s 
                 "%d %[0-9-+ ]" 
                 (fun n rest_str -> n :: int_list_of_string rest_str)
  with
    | End_of_file | Scanf.Scan_failure _ -> []

这里的技巧是将输入字符串s表示为将被解析为整数(%d)的部分,并使用范围格式表示字符串的其余部分:{{ 1}},它将匹配字符串的其余部分,仅包含小数位数%[0-9-+ ]"0-9-符号以及空格+