Как правильно использовать Lwt_io.read_int?
Как правильно использовать 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
)
2 ответа
Это читает двоичное кодированное целое число, например, для десериализации некоторых данных из файла.
Вы читаете 875770417, который находится в шестнадцатеричном формате 0x34333231, что в свою очередь соответствует кодировке ASCII '1', '2', '3' и '4' в порядке с прямым порядком байтов.
Вы, вероятно, хотите прочитать строку, используя Lwt_io.read_line
и преобразовать результат, используя int_of_string
,
Согласно этой странице, я попробовал несколько экспериментов.
Сначала я написал:
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
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
Что именно "001"
в ASCII.
Я надеюсь, что это поможет вам выяснить, какую функцию использовать. По моему скромному мнению, я не понимаю, почему читать целое число (и это точно так же, как с float64
или же int64
но это время ограничено 7 цифрами) кажется так сложно. Я бы предложил использовать read_line
а также int_of_string
по крайней мере, это работает хорошо.