【问题标题】:What's the proper usage for Lwt_io.read_int?Lwt_io.read_int 的正确用法是什么?
【发布时间】:2017-05-19 10:15:08
【问题描述】:

如何正确使用 Lwt_io.read_int?我尝试了我认为明显的用法,但没有得到明显的结果......

open Lwt.Infix

let _ =
  Lwt_main.run
    (
      Lwt_io.print "Enter number: " >>=
      fun () -> Lwt_io.read_int (Lwt_io.stdin) >>=
      fun d -> Lwt_io.printf "%d\n" d
    )

我编译、运行并在提示时输入12345,程序显示875770417。

我在这里遗漏了一些东西......

在下面的帮助下,我做到了这一点。它有效,我希望它是正确的。

open Lwt.Infix

let _ =
  Lwt_main.run
    (
      Lwt_io.print "Enter number: " >>=
      fun () -> Lwt_io.read_line (Lwt_io.stdin) >>=
      fun s -> 
      (
        try
          Lwt.return_some( Pervasives.int_of_string s)
        with
        | _ -> Lwt.return_none
      ) >>=
      fun o -> 
      Lwt_io.print
        (
          match o with
          | Some i -> Printf.sprintf "%d\n" i
          | None -> "Ooops, invalid format!\n"
        )
    )

我想我应该发布一些代码来演示 Lwt_io.read_int 的正确用法。

open Lwt.Infix
open Lwt_io

let _ =
  Lwt_main.run
    (
      let i, o = Lwt_io.pipe() in
      Lwt_io.write_int o 1 >>=
      fun () -> Lwt_io.flush o >>=
      fun () -> Lwt_io.close o >>=
      fun () -> Lwt_io.read_int i >>=
      fun d -> Lwt_io.printf "%d\n" d >>=
      fun () -> Lwt_io.close i
    )

【问题讨论】:

    标签: ocaml ocaml-lwt


    【解决方案1】:

    这会读取一个二进制编码的整数,例如为了反序列化文件中的一些数据。

    您读到的 875770417 是十六进制 0x34333231,它依次对应于小端序中的 '1'、'2'、'3' 和 '4' 的 ASCII 编码。

    您可能希望使用Lwt_io.read_line 读取字符串并使用int_of_string 转换结果。

    【讨论】:

      【解决方案2】:

      根据这个page,我尝试了一些实验。

      首先,我写道:

      open Lwt.Infix
      
      let _ =
        Lwt_main.run
          (
            let open Lwt_io in
            print "Enter number: " >>=
              fun () -> read_line stdin >>=
            fun d -> printlf "%s" d
          )
      

      我得到了我想要的所有输出。

      好的,现在让我们尝试使用整数,因为它是这样写的

      val read_int : Lwt_io.input_channel -> int Lwt.t

      将 32 位整数读取为 ocaml int

      open Lwt.Infix
      
      let _ =
        Lwt_main.run
          (
            let open Lwt_io in
            print "Enter number: " >>=
              fun () -> read_int stdin >>=
            fun d -> write_int stdout d
          )
      

      好吧,这里有奇怪的行为:

      lhooq@lhooq-linux lwt_io $ ./main.native 
      Enter number: 100
      100
      lhooq@lhooq-linux lwt_io $ ./main.native 
      Enter number: 1000
      1000lhooq@lhooq-linux lwt_io $ ./main.native 
      Enter number: 10000
      1000lhooq@lhooq-linux lwt_io $ 
      lhooq@lhooq-linux lwt_io $ ./main.native 
      Enter number: 10
      20
      10
      2lhooq@lhooq-linux lwt_io $
      

      所以,看起来这个函数可以处理的最大值是三位数,但至少它会打印出你写的数字。

      下一个测试:

      open Lwt.Infix
      
      let _ =
        Lwt_main.run
          (
            let open Lwt_io in
            print "Enter number: " >>=
              fun () -> read_int stdin >>=
            fun d -> printlf "%d" d
          )
      

      正是你的问题:

      lhooq@lhooq-linux lwt_io $ ./main.native 
      Enter number: 100
      170930225
      

      让我们这样写吧:

      open Lwt.Infix
      
      let _ =
        Lwt_main.run
          (
            let open Lwt_io in
            print "Enter number: " >>=
              fun () -> read_int stdin >>=
            fun d -> eprintf "%x\n" d
          )
      

      然后再次测试:

      lhooq@lhooq-linux lwt_io $ ./main.native 
      Enter number: 100
      a303031
      

      这正是 ASCII 中的 "001"

      我希望这将帮助您确定要使用的功能。以我的拙见,我不明白为什么读取整数(与float64int64 完全相同,但这次限制为7 位)似乎如此困难。我建议使用read_lineint_of_string,因为至少这很好用。

      【讨论】:

        猜你喜欢
        • 2013-03-09
        • 2011-04-15
        • 1970-01-01
        • 2012-10-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多