challenge 固定長データ

固定長のデータが記載されたファイルを読み込むプログラムを作成してください。読み込んだデータは、複数の値を格納できるデータ型に格納してください。

ファイルには、すべて ascii 文字で以下のデータが格納されています。デリミタはなく、固定長で格納されています。レコードとレコードのあいだも改行はありません。

  1. 姓 (12文字) 文字数が足りない場合は、後ろを空白で埋めてあります。
  2. 名 (12文字) 文字数が足りない場合は、後ろを空白で埋めてあります。
  3. 性別 (F,M,Uの3種類、1文字)
  4. 年齢 (3桁の数字、桁数が足りない場合は、ゼロで埋めず、頭を空白で埋めてあります。
  5. 年 2008 固定
  6. 月 03 固定
  7. さらに以下のデータが日付分くりかえされます。
    1. 日付 (01 〜 31) 2文字
    2. 朝食のメニュー (500文字)
    3. 昼食のメニュー (500文字)
    4. 夕食のメニュー (500文字)

以上の形式のデータ500人分を読みこんで、データを複数の値を格納できるデータ型に格納してください。データに大して何か処理を行う必要はなく、すぐに破棄してかまいません。

この問題は、このようなファイルをどのように扱うかを知りたくて作成しました。

Posted feedbacks - Erlang

なんかもっといい書き方がある気がする。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
-module(scan1).
-compile(export_all).
-define(SZ,46596).
-define(MSZ,1502).
-define(CNT,500).
-record(person,{fname,sname,sex,age,year,month,menus=[]}).
-record(menu,{day,breakfast,lunch,dinner}).

start() ->
    {ok,S}=file:open("data.txt",[read,raw]),
    scan(S,0,0),
    file:close(S).

scan(_,_,?CNT) ->
    ok;
scan(S,N,C) ->
    case file:pread(S,N,?SZ) of
        eof ->
            ok;
        {ok,R} ->
            P=#person{
              fname=string:strip(string:substr(R,1,12),right,$ ),
              sname=string:strip(string:substr(R,13,12),right,$ ),
              sex=string:substr(R,25,1),
              age=string:strip(string:substr(R,26,3),left,$ ),
              year=string:substr(R,29,4),
              month=string:substr(R,33,2),
              menus=scanm(string:substr(R,35))
             },
            erlang:display(P),
            scan(S,N+?SZ,C+1)
    end.

scanm(R)->
    scanm(R,[],1).
scanm(_,L,31) ->
    L;
scanm(R,L,N)->
    M=#menu{
      day=string:substr(R,1,2),
      breakfast=string:strip(string:substr(R,3,500),right,$ ),
      lunch=string:strip(string:substr(R,503,500),right,$ ),
      dinner=string:strip(string:substr(R,1003,500),right,$ )
     },
    scanm(string:substr(R,?MSZ+1),L++[M],N+1).

もいっこビット構文式を使った手抜き版

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
-module(scan2).
-export([start/0]).

start() ->
    {ok,S}=file:open("getrec.txt",[read,binary,raw]),
    erlang:display(binary_to_list(element(1,lists:nth(1,scan(S,[],0,0))))),
    file:close(S).

scan(_,L,_,500)->
    L;
scan(S,L,N,C) ->
    case file:pread(S,N,46596) of
        eof ->
            ok;
        {ok,<<FName:12/binary,SName:12/binary,Sex:1/binary,
             Age:3/binary,Year:4/binary,Month:2/binary,Menus/binary>>} ->
            scan(S,L++[{FName,SName,Sex,Age,Year,Month,scan_menu(Menus,[],1)}],N+46596,C+1)
    end.

scan_menu(_,L,31)->
    L;
scan_menu(M,L,C) ->
    {D,R}=split_binary(M,1502),
    <<Day:2/binary,Breakfast:500/binary,Lunch:500/binary,Dinner:500/binary>> = D,
    scan_menu(R,L++[Day,Breakfast,Lunch,Dinner],C+1).

Index

Feed

Other

Link

Pathtraq

loading...