Reputation: 15
-module(test).
-export([run/1]).
open_file(FileName, Mode) ->
{ok, Device} = file:open(FileName, [Mode, binary]), Device.
close_file(Device) ->
ok = file:close(Device).
read(File) ->
case file:read_line(File) of
{ok, Data} -> [Data | read(File)];
eof -> []
end.
run(InputFileName) ->
Device = open_file(InputFileName, read),
Data = read(Device),
[First |TheRest] = Data,
io:format("First line is ~p ~n", [First]),
close_file(Device).
The original file
d1 and is program program the
d2 a apply copyleft free free freedom
d3 copyleft copyleft share share users
d4 released software works
d5 licenses licenses licenses licenses licenses software
d8 apply
somehow turns into
50> test:run("input.txt").
First line is <<"d1\tand\tis\tprogram\tprogram\tthe\n">>
ok
Is this a special way of representing a list? or do I need to use kind of module to convert the read into a list?
My ultimate goal is to make a key pair with a list:
{d1 [and is program program the]}
Thank you!
Upvotes: 1
Views: 330
Reputation: 20024
The data you're reading from your file is represented as a binary, rather than a string, because you're specifying binary
mode when you open the file:
{ok, Device} = file:open(FileName, [Mode, binary]), Device.
If you change this to:
{ok, Device} = file:open(FileName, [Mode]), Device.
your result becomes:
First line is "d1 and is program program the\n"
To get the ultimate result, change your read/1
function to this:
read(File) ->
case file:read_line(File) of
{ok, Data} ->
[First|Rest] = string:tokens(Data, " \t\n"),
[{First,string:join(Rest, "\t")} | read(File)];
eof -> []
end.
With this change, your program prints:
First line is {"d1","and\tis\tprogram\tprogram\tthe"}
where the second element is a string in which the tokens are tab-separated as in your original data. If you want the first element, "d1"
, to instead be an atom d1
(I can't tell for sure from your question if this is what you want), you can convert it with list_to_atom/1
.
Upvotes: 1