Domanda

I have the following code to read lines from a file

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

However, this code adds additional "\" to characters "\n".
E.g.

helloworld\n

gets read into

helloworld\\n

How shall I turn off this so that I get helloworld\n instead?
Thank you very much!

EDIT

So I have tested with this:

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

The output is helloworld\n instead of helloworld with a new line.

È stato utile?

Soluzione

I seriously doubt that extra characters are being introduced by this code. Most likely you're just misreading the output of the toplevel. If you write out the string with print_string you'll see the actual contents.

I assume your input line actually contains helloworld\n (12 characters, plus the newline at the end).

Here is a test session on 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 = ()

The line length is correct (12 chars). The extra backslash is just the way the toplevel writes a backslash in a string.

Update

Your test file apparently contains an actual \n (two characters), so naturally this is what shows up on the output. If you don't want the \n to show up in the output, you should remove it from the input :-)

Update 2

I can't shake the feeling that you might not be used to thinking about text files at a low level. If this is true, here are some things to think about.

  • Lines in a Unix style text file already have newlines at the end. You don't need to put \n in the file to represent the end of the line. Your text editor (or other text handling app) will put newlines in for you at the ends of lines.

  • The OCaml function input_line removes these newlines (because they're redundant--there's one at the end of every line).

  • If you want these newlines to appear in your list of lines, you can add them back yourself with input_line chan ^ "\n" or similar.

  • Or you can write lines out using print_endline which writes the newline for you.

(My apologies if you already knew about this.)

Altri suggerimenti

Here is what I did for the parsing with 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;;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top