Scanf模块的行为似乎有些违背直觉,因为它不尊重底层通道的状态:
(* prepare test data *)
let () =
let oc = open_out "test.txt" in
output_string oc "abcdefghij\n";
close_out oc
;;
let ic = open_in "test.txt"
(* ic at offset 0: “ab…” *)
let () =
let sc = Scanf.Scanning.from_channel ic in
let s = Scanf.bscanf sc "%2s" (fun s -> s) in
Printf.eprintf "read [%s]\n" s (* -> [ab] *)
;; (* sc out of scope at this point *)
(* hint: close ic here and reopen for expected result *)
seek_in ic 4
(* ic at offset 4: “ef…” *)
let () =
let sc = Scanf.Scanning.from_channel ic in
let s = Scanf.bscanf sc "%2s" (fun s -> s) in
Printf.eprintf "read [%s]\n" s (* -> [cd] ‽ *)
;;
close_in ic显然,除非重新创建通道,Scanning.t的内部缓冲区才能生存下来。还有别的方法来强迫重新合成吗?文档声称“阅读从ic当前的阅读位置开始。”
我很想知道这个行为到底在哪里被记录下来。
发布于 2017-02-18 01:51:37
关于一般的设计原则,我想说的是,对Scanf.Scanning.from_channel的调用会将通道的责任转移到Scanf模块。如果您在Scanf模块后面直接操作通道(就像这里对seek_in所做的那样),就不能保证一切都能正常工作。
实际上,对于我使用过的每一个分层I/O库,情况都是类似的。例如,您不能使用Unix中的fdopen()并期望通过FILE抽象来读取数据,同时也可以任意地操作底层文件描述符。
如果文档提到这些问题(在这两种情况下),可能会更好。
https://stackoverflow.com/questions/42309522
复制相似问题