ファイル入出力の応用例として、決められた商品に対する、 支払金額計算プログラムを作ろう。以下のような仕様のプログラムを作りたい。
実際にプログラムを動かすときのシミュレーションをしてみると プログラムの設計方針を立てやすいだろう。
以下のように、商品と価格の書かれたファイルがあったとする。
サーモン 110円 イカゲソ 110円 えんがわ 110円 マグロ 110円 ネギトロ 110円 蛸 110円 赤貝 110円 穴子 110円 鉄火巻 110円 カッパ巻 110円 ハマチ 110円 サヨリ 180円 中トロ 180円 牛トロ 180円 寒ブリ 180円 イクラ 240円 タラバ 240円 大トロ 360円 ウニ 360円
プログラムを起動すると、このファイルを自動的に読み込み、その内容を メニュー番号とともに標準出力に出す。
0 サーモン 110円 1 イカゲソ 110円 2 えんがわ 110円 3 マグロ 110円 4 ネギトロ 110円 5 蛸 110円 6 赤貝 110円 7 穴子 110円 8 鉄火巻 110円 9 カッパ巻 110円 10 ハマチ 110円 11 サヨリ 180円 12 中トロ 180円 13 牛トロ 180円 14 寒ブリ 180円 15 イクラ 240円 16 タラバ 240円 17 大トロ 360円 18 ウニ 360円
ユーザがメニュー番号を順次入力し終えるとそれまで入力したメ ニューの価格を全て足した金額を出力する。
全部で2490円でございます。
上記の動作イメージから分かることは、プログラムのおおまかな流れとして
price.txt
)を読み、品目と金額
を全て記憶する。の3つがある。最後に合計金額を出力するので 2.のところで、 つねに金額を足していなければならない。これらのことに注意して 各段階の手順をプログラムにしていこう。
まず、price.txt
データファイルから価格リストを読み
込み商品名を配列変数に入れる部分を作ろう。さらにその値段部分を別の
配列変数に入れておこう。ここでは商品名を入れる配列を
menu
変数、価格を入れる配列をprice
変数としよう。するとプログラムの該当部分は
以下のようになる。
menu = [] price = [] i = 0 open("price.txt", "r") do |neta| # price.txtを読み込みモードで開く while line = neta.gets # ファイルから1行ずつ読む if /(\S+)\s+(\d+)円/ =~ line # (数字)円 というパターンがあれば menu << $1 # $1 は商品名 price << $2.to_i # $2 が「数字」に当てはまるので整数化 printf("%3d %s", i, line) # 商品番号と、読み込んだ行を出力 i += 1 end end end
商品データの読み込みが完了したときの i
の値は、「最後の商品番号+1」が入っていることを踏まえて
以下に進もう。
続いてユーザが対話入力で、商品番号を入れるループを作ろう。
注文が終わったら "q"
を入力する約束にしてループを作成する。
while true print "御注文は(番号で入れてね、q で終了)?: " line=gets.chomp! # ユーザの入力を line に入れる if line == "q" # "q" を入力したら break # 終了 end number = line.to_i # 整数(メニュー番号)にする if number < 0 || number >= menu.length puts "そんなメニューねぇでガス" redo end printf("はあーい、「%s」一丁\n", menu[number]) sum += price[number] end
変数 sum
に入っている合計金額を出力して終了する。
print "おあいそでガス\n" printf("全部で %d 円でガス。まいどっ\n", sum)
以上を組み合わせることでプログラムが完成する。
#!/usr/koeki/bin/ruby # -*- coding: utf-8 -*- sum = 0 menu = [] price = [] i = 0 open("price.txt", "r") do |neta| # price.txtを読み込みモードで開く while line = neta.gets # ファイルから1行ずつ読む if /(\S+)\s+(\d+)円/ =~ line # (数字)円 というパターンがあれば menu << $1 # $1 は商品名 price << $2.to_i # $2 が「数字」に当てはまるので整数化 printf("%3d %s", i, line) # 商品番号と、読み込んだ行を出力 i += 1 end end end while true print "御注文は(番号で入れてね、q で終了)?: " line=gets.chomp! # ユーザの入力を line に入れる if line == "q" # "q" を入力したら break # 終了 end number = line.to_i # 整数(メニュー番号)にする if number < 0 || number >= menu.length puts "そんなメニューねぇでガス" redo end printf("はあーい、「%s」一丁\n", menu[number]) sum += price[number] end print "おあいそでガス\n" printf("全部で %d 円でガス。まいどっ\n", sum)
sushi.rb
と
price.txt
を保存し、実際に実行してみ
よう。
./sushi.rb