scanf 不接受第一个参数
scanf not accepting first arg
以下代码运行没有错误:
let f x y =
print_int (max x y);
print_char ' ';
print_int (x + y) in
for i = 1 to Scanf.scanf "%d" (fun x -> x) do
Scanf.scanf "\n%d %d" f;
print_newline ();
done;
但是当我声明一个变量 fmt 来保存格式“\n%d %d”并将它传递给 scanf 时,我得到一个错误,这是新代码:
let f x y =
print_int (max x y);
print_char ' ';
print_int (x + y) in
let fmt = "\n%d %d" in (* added *)
for i = 1 to Scanf.scanf "%d" (fun x -> x) do
Scanf.scanf fmt f; (* edited *)
print_newline ();
done;
我收到这个错误:
File "prog.ml", line 7, characters 16-19:
Error: This expression has type string but an expression was expected of type
('a, Scanf.Scanning.in_channel, 'b, 'c -> 'd, 'a -> 'e, 'e) format6
为什么它的工作方式不同?这两个代码之间有什么区别吗?
OCaml 中 printf/scanf 格式的处理使用了一些编译器魔法,将字符串 constant 视为适当上下文中的格式。问题是您不再有字符串常量。
您可以使用 format_of_string
函数将字符串常量预转换为格式。
将您的 let fmt =
行更改为:
let fmt = format_of_string "\n%d %d" in
这让你的代码对我有用。
虽然看起来很奇怪,但这实际上是一个增值功能:扫描函数在编译时进行类型检查,为了做到这一点,编译器必须能够清楚地看到格式字符串呼叫站点并确保没有恶作剧正在进行中。此类恶作剧可能会导致不良行为,如下例所示:
let fmt = "%d" in
let fmt' = fmt ^ (if input_type = "int" then " %d" else " %f") in
(* input_type is defined somewhere else in the program *)
(* the format string could now be either "%d %d" or "%d %f" *)
let a,b = Scanf.scanf fmt' (fun a b -> a,b)
(* the compiler cannot infer a type for `b` *)
以下代码运行没有错误:
let f x y =
print_int (max x y);
print_char ' ';
print_int (x + y) in
for i = 1 to Scanf.scanf "%d" (fun x -> x) do
Scanf.scanf "\n%d %d" f;
print_newline ();
done;
但是当我声明一个变量 fmt 来保存格式“\n%d %d”并将它传递给 scanf 时,我得到一个错误,这是新代码:
let f x y =
print_int (max x y);
print_char ' ';
print_int (x + y) in
let fmt = "\n%d %d" in (* added *)
for i = 1 to Scanf.scanf "%d" (fun x -> x) do
Scanf.scanf fmt f; (* edited *)
print_newline ();
done;
我收到这个错误:
File "prog.ml", line 7, characters 16-19:
Error: This expression has type string but an expression was expected of type
('a, Scanf.Scanning.in_channel, 'b, 'c -> 'd, 'a -> 'e, 'e) format6
为什么它的工作方式不同?这两个代码之间有什么区别吗?
OCaml 中 printf/scanf 格式的处理使用了一些编译器魔法,将字符串 constant 视为适当上下文中的格式。问题是您不再有字符串常量。
您可以使用 format_of_string
函数将字符串常量预转换为格式。
将您的 let fmt =
行更改为:
let fmt = format_of_string "\n%d %d" in
这让你的代码对我有用。
虽然看起来很奇怪,但这实际上是一个增值功能:扫描函数在编译时进行类型检查,为了做到这一点,编译器必须能够清楚地看到格式字符串呼叫站点并确保没有恶作剧正在进行中。此类恶作剧可能会导致不良行为,如下例所示:
let fmt = "%d" in
let fmt' = fmt ^ (if input_type = "int" then " %d" else " %f") in
(* input_type is defined somewhere else in the program *)
(* the format string could now be either "%d %d" or "%d %f" *)
let a,b = Scanf.scanf fmt' (fun a b -> a,b)
(* the compiler cannot infer a type for `b` *)