【问题标题】:OCaml read \n characterOCaml 读取 \n 字符
【发布时间】:2014-05-05 21:50:30
【问题描述】:

我有以下代码从文件中读取行

let read_file filename =
  let lines = ref [] in
  let chan = open_in filename in
  try
    while true do
      lines := input_line chan :: !lines
    done;
    !lines
  with End_of_file ->
    close_in chan;
    List.rev !lines

但是,此代码在字符“\n”中添加了额外的“\”。
例如。

helloworld\n

被读入

helloworld\\n

我应该如何关闭它以便获得helloworld\n?
非常感谢!

编辑

所以我用这个测试了:

let read_file filename =
  let lines = ref [] in
  let chan = open_in filename in
  try
    while true do
      lines := input_line chan :: !lines
    done;
    !lines
  with End_of_file ->
    close_in chan;
    List.rev !lines

let () =
  let lines = read_file "test.txt" in
  for i=1 to List.length lines
  do
    Printf.printf("%s") (List.nth lines (i-1))
  done;

test.txt

helloworld\n

输出是helloworld\n,而不是helloworld,换行。

【问题讨论】:

    标签: string ocaml


    【解决方案1】:

    我严重怀疑这段代码是否引入了额外的字符。很可能您只是误读了顶层的输出。如果你用print_string 写出字符串,你会看到实际的内容。

    我假设您的输入行实际上包含 helloworld\n(12 个字符,加上末尾的换行符)。

    这是在 OS X 10.9.2 上的测试会话

    $ od -c myfile
    0000000    h   e   l   l   o   w   o   r   l   d   \   n  \n        
    0000015
    $ ocaml
            OCaml version 4.01.0
    
    # let read_file filename =
    ... copy your definition above ...
    # let lines = read_file "myfile";;
    val lines : string list = ["helloworld\\n"]
    # String.length (List.nth lines 0);;
    - : int = 12
    # print_string (List.nth lines 0);;
    helloworld\n- : unit = ()
    

    行长正确(12 个字符)。额外的反斜杠只是顶层在字符串中写入反斜杠的方式。

    更新

    您的测试文件显然包含一个实际的\n(两个字符),所以这自然会出现在输出中。如果您不希望 \n 出现在输出中,则应将其从输入中删除 :-)

    更新 2

    我无法摆脱您可能不习惯在低层次上考虑文本文件的感觉。如果这是真的,这里有一些事情需要考虑。

    • Unix 样式文本文件中的行已经在末尾有换行符。您无需将\n 放入文件中以表示行尾。您的文本编辑器(或其他文本处理应用程序)会在行尾为您添加换行符。

    • OCaml 函数input_line 删除这些换行符(因为它们是多余的——每一行的末尾都有一个)。

    • 如果您希望这些换行符出现在您的行列表中,您可以使用 input_line chan ^ "\n" 或类似名称自行添加。

    • 或者你可以使用print_endline写出换行符。

    (如果您已经知道这件事,我深表歉意。)

    【讨论】:

    • 感谢您的帮助。是的,我得到相同的结果。我可能用错了措辞,但我想要“helloworld\n”,这样当我运行打印时,它会打印出“helloworld”和一个新行而不是“\n”。
    • 如果您打印字符串,它将执行此操作。它只是显示额外反斜杠的顶层(以消除解释 REPL 结果的歧义)。
    • 如果您希望输入文件中的\n(两个字符)在输出时转换为换行符(一个字符),您必须编写进行翻译的代码。它不会自动发生。
    【解决方案2】:

    这是我为解析 Str.regexp 所做的

    let newlinereg = Str.regexp "\\\\n" in                                                                                                                                                      
    let replacednewline = Str.global_replace newlinereg "\n" output_string in                                                                                                                                                              
    let tabreg = Str.regexp "\\\\t" in                                                                                                                                                  
    let final_string = Str.global_replace tabreg "\t" replacednewline in
    final_string;;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-28
      • 1970-01-01
      • 1970-01-01
      • 2017-09-29
      • 1970-01-01
      • 2016-04-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多