2012-04-24 5 views
3

Я пытаюсь прочитать целочисленное значение из простого текстового файла. Row в моем входном файле выглядит следующим образом:Erlang: Чтение целых чисел из файла

1 4 15 43 
2 4 12 33 
... (many rows of 4 integers) 

Я открыл файл следующим образом:

{ok, IoDev} = file:open("blah.txt",[read]) 

Но единственное, что я управляю читать байты со всеми функциями доступными.

Что я, наконец, хочу получить из файла, это кортежи целых чисел.

{1 4 15 43} 
{2 4 12 33} 
... 

ответ

3

Вы должны сначала использовать file:read_line/1 для чтения строки текста, а также использовать re:split/2, чтобы получить список строк, содержащих числа. Затем используйте list_to_integer BIF для получения целых чисел.

Вот пример (конечно, есть лучшее решение):

#!/usr/bin/env escript 
%% -*- erlang -*- 

main([Filename]) -> 
    {ok, Device} = file:open(Filename, [read]), 
    read_integers(Device). 

read_integers(Device) -> 
    case file:read_line(Device) of 
    eof -> 
     ok; 
    {ok, Line} -> 
     % Strip the trailing \n (ASCII 10) 
     StrNumbers = re:split(string:strip(Line, right, 10), "\s+", [notempty]), 
     [N1, N2, N3, N4] = lists:map(fun erlang:list_to_integer/1, 
        lists:map(fun erlang:binary_to_list/1, 
          StrNumbers)), 
     io:format("~w~n", [{N1, N2, N3, N4}]), 
     read_integers(Device) 
    end. 

(EDIT)

Я нашел несколько более простое решение, которое использует io:fread читать форматированный ввод. Он хорошо работает в вашем случае, но плохо работает, когда файл плохо сконструирован.

#!/usr/bin/env escript 
%% -*- erlang -*- 

main([Filename]) -> 
    {ok, Device} = file:open(Filename, [read]), 
    io:format("~w~n", [read_integers(Device)]). 

read_integers(Device) -> 
    read_integers(Device, []). 

read_integers(Device, Acc) -> 
    case io:fread(Device, [], "~d~d~d~d") of 
    eof -> 
     lists:reverse(Acc); 
    {ok, [D1, D2, D3, D4]} -> 
     read_integers(Device, [{D1, D2, D3, D4} | Acc]); 
    {error, What} -> 
     io:format("io:fread error: ~w~n", [What]), 
     read_integers(Device, Acc) 
    end. 
+0

Спасибо, я думаю, что это будет делать. Я всегда искал пакет файлов и никогда не советовался с io. Благодаря! – lucafik

2

не видел отредактированный часть

/*

Вы можете попробовать fread/3

read() -> 
{ok, IoDev} = file:open("x", [read]), 
read([], IoDev). 

read(List, IoDev) -> 
case io:fread(IoDev, "", "~d~d~d~d") of 
{ok, [A,B,C,D]} -> 
    read([{A,B,C,D} | List], IoDev); 
eof -> 
    lists:reverse(List); 
{error, What} -> 
    failed 
end. 

*/

Смежные вопросы