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 - Common Lisp

とりあえず。うまくマクロを書けばもっときれいになるでしょう。

 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
(defstruct menu
  date breakfast lunch dinner)

(defstruct person
  family-name first-name sex age year month menus)

(defun scan-string (stream length &optional string)
  (let ((s (or string (make-string length))))
    (read-sequence s stream)
    s))

(defun scan-integer (stream n &optional (radix 10))
  (parse-integer (scan-string stream n) :radix radix :junk-allowed t))

(defun scan-list (stream length scanner &rest args)
  (loop repeat length collect (apply scanner stream args)))

(defun scan-menu (stream)
  (let ((date (scan-integer stream 2))
        (breakfast (scan-string stream 500))
        (lunch (scan-string stream 500))
        (dinner (scan-string stream 500)))
    (make-menu :date date :breakfast breakfast :lunch lunch :dinner dinner)))

(defun scan-person (stream)
  (let ((family-name (scan-string stream 12))
        (first-name (scan-string stream 12))
        (sex (scan-string stream 1))
        (age (scan-integer stream 3))
        (year (scan-integer stream 4))
        (month (scan-integer stream 2))
        (menus (scan-list stream 31 #'scan-menu)))
    (make-person :family-name family-name :first-name first-name
                 :sex sex :age age :year year :month month :menus menus)))

(defun scan-record (stream)
  (scan-list stream 500 #'scan-person))

(defun read-record-from-file (file)
  (with-open-file (s file) (scan-record s)))

Index

Feed

Other

Link

Pathtraq

loading...