参考として、良かったレポートを示す。
氏名: fx
学籍番号: c111126
クラス: 中国語1
1.作成したプログラム
#!/usr/bin/koeki/ruby
# coding:euc-jp
name = []
kin = []
i = n = sum = 0
open("receipt.txt","r") do |hoge|
while line = hoge.gets
if /^#/ =~ line
next
elsif /^"(.+)"\s+(\d+)\s+(\d+)\s+(\d+)/ =~ line
name[i] = $1
kin[i] = $4.to_i
sum += $4.to_i
i += 1
end
end
end
open("result.txt","w") do |hoge|
hoge.print"+-----------------------------+\nSHOP HOGEHOGE\n --------\n |領収書|\n --------\n+-----------------------------+\n"
while n < i
hoge.printf(" %-20s%8d円\n",name[n],kin[n])
n += 1
end
hoge.printf("+-----------------------------+\n 合計%20d円\n+-----------------------------+\n",sum)
end
5番のreceipt.txt にあるデータを入力として 購入したものや合計金額などを
本物のレシートのような 書式で result.txt ファイルに出力するプログラム
open5.rbを作成した。
2.プログラムを動かした結果画面と、その結果ファイルの内容
roy{c111126}% ruby open5.rb [~/Ruby]
roy{c111126}% cat result.txt [~/Ruby]
+-----------------------------+
SHOP HOGEHOGE
--------
|領収書|
--------
+-----------------------------+
モコモコスパゲッティ 880円
suidou ざ・movie 3980円
SDHC 4GB 980円
5フィンガー靴下 120円
+-----------------------------+
合計 5960円
+-----------------------------+
3.プログラムの説明
最初の2行はおまじない
4,5行目の
name = []
kin = []
でnameという配列とkinという配列を作っている
また、6行目の
i = n = sum = 0
で、数える用のiとn、合計を入れるためのsumという変数に0を入れている
7行目の
open("receipt.txt","r") do |hoge|
では、receipt.txtというファイルを読み込みモードで開いている
8行目の
while line = hoge.gets
では、7行目に読み込んだデータを一行ずつlineという変数の中に読み込み、デー
タが読めなくなったらループを終わるという条件を設定している。
9,10行目の
if /^#/ =~ line
next
では、読み込んだデータの先頭が#だった場合は、その行はメモでデータではな
いので次のデータを読みなおすようにしている。
11行目の
elsif /^"(.+)"\s+(\d+)\s+(\d+)\s+(\d+)/ =~ line
では、読み込んだデータの形が
^ 先頭に
"(.+)" ""で囲まれた文字が一つ以上続き、(商品名)
\s+ 空白が一つ以上続き、(商品名と分類コードの間の空白)
(\d+) 数字が一つ以上続き、(分類コード)
\s+ 空白が一つ以上続き、(分類コードと商品コードの間の空白)
(\d+) 数字が一つ以上続き、(商品コード)
\s+ 空白が一つ以上続き、(商品コードと価格の間の空白)
(\d+) 数字が一つ以上続いている(価格)
時に、
/^"(.+)"\s+(\d+)\s+(\d+)\s+(\d+)/
$1 $2 $3 $4
の順にデータを取るというif文にしている
12,13行目の
name[i] = $1
kin[i] = $4.to_i
では、nameという配列のi番目に読み込んだデータの$1の位置にある名前を入れ
て、kinという配列のi番目に読み込んだデータの$4の位置にある価格を入れ、数
字として出すために.to_iを付けている。
14行目の
sum += $4.to_i
では、合計用の変数sumに$4に入っている価格を.to_iを付けて数字として持って
来て足していくようにしている。
15行目の
i += 1
では、配列の入れる位置をずらす為に1ずつ足している。また、ここでデータの
件数も数えている。
16,17,18行目の
end
は、それぞれ9行目のif文、8行目のwhile文、7行目のopenを閉じるためのもので
ある。
19行目の
open("result.txt","w") do |hoge|
では、result.txtというファイルを書き込み形式で開き、無ければ新規作成して、
既にあれば中身を何も無くしてから書き込むようにしている。
20行目の
hoge.print"+---...---+\n"
では、外部に出力するために19行目で設定した変数をpirntの前に付けて、レシー
トの飾りになる部分を表示している。
21行目の
while n < i
では、件数を数えていたiよりもnが小さい間ループを続けるという条件で設定し
ている。
22行目の
hoge.printf(" %-20s%8d円\n",name[n],kin[n])
では、printfの前に外部に出力するための変数を付け、実際に表示する商品名が
入っている配列nameのn番目と、価格が入っている配列kinのn番目を、それぞれ
%-20s,%8dで表示している。
23行目の
n += 1
では、22行目で表示するn番目をずらすためと、件数を数えているiと比べるため
にnに1ずつ足している。
24行目の
end
は、23行目のwhile文を閉じる為のものである。
25行目の
hoge.printf("+----...--+\n 合計 %20d円\n+---...---+\n,sum)
では、レシートを横線で閉じ、金額の合計を入れていたsumを表示して、レシー
トをまた横線で閉じているように表示している。
26行目の
end
は、19行目のopenを閉じる為のものである。
4.考察
データを読み込む正規表現を書く時に、ただ
/^(\S+)\s+(\d+)\s+(\d+)\s+(\d+)/
とやると、suidou ざ・movieなど、商品名の間に空白があるものに上手く当ては
まらなくなる。なので、データの中の商品名が""で囲まれている事を利用し、
/^"(.+)"\s+(\d+)\s+(\d+)\s+(\d+)/
とすることで、""に囲まれている文字というように選択でき、上手く正規表現に
当てはめる事が出来る。
5.参考文献
広瀬雄二."ファイル入出力".東北公益文化.
http://roy/~yuuji/2012/pf1/07/file-io.html,(参照2012-5-8)
6.感想
openコマンドはこれからよく使う事になると思うので、しっかり使いこなせるよ
うにしたいと思う。
メールを送るコマンド等も復習して、これから先グループ課題等を作る事になっ
た時に活用出来るようにしていけるようにしたい。