🧩今日の学び
・入力はそのまま使わず、「判定 → 変換 → 使用」の順で処理するのが安全設計の基本
・なるおの気づきの通り、NUMVALは便利だが無理やり変換するため、事前チェックが必須
・COBOLは入力を信用せず、プログラマが責任を持って検証する言語である
係長)では、計算ロジックと終了判定行くぞ。
なるお)あいー
係)流れは、こうだったな。
TOTAL = 0 入力 → X IF "=" → 終了 TOTAL = TOTAL + X 繰り返し
そして、すでに変数は宣言済みでこうだったかな。
01 X PIC 9(3) VALUE 0. 01 TOTAL PIC 9(3) VALUE 0. 01 Y PIC X.
な)ふむふむ
係)ここから進めてみろ。今お前が持ってる材料でいけるはずだ。
な)えーと…
「入力→X」だとして、ACCEPT Xで数字を入れていけば、良さそうかな?でも「=を入れる」もあるよね。
ACCEPT Xを使ったとして、勝手に数字と文字を選り分けてくれるわけじゃないすよね?COBOLは「融通きかないくん」だし。もう脳に電極繋いで意思通りに動いてくれればいいのに。
係)まったく、あっさり騙されたな。
な)え?
係)前回のこと覚えてるか?
その変数宣言は、TOTAL の桁数が PIC 9(3) に戻ってる。
昨日のオーバーフロー対策の「防波堤」の話は忘れてるだろ。
な)あ…。
なんちゅー性格の悪さ!
係)なんでだよ!
な)だって、係長が書いたんだから、間違いないって思うじゃないっすか!閻魔大王さえ騙そうとするレベルっすよ!それでも俺はやってないっすか!?
係)そういういいから!
それと、入力用の Y だが、PIC X のままだと「1文字」しか入らんぞ。
Xと合わせるならPIC X(3) くらいに太らせておけよ。
な)むー。
01 X PIC 9(3) VALUE 0. 01 TOTAL PIC 9(5) VALUE 0. 01 Y PIC X(3).
ってことっすよね?
係)OKだな。
ACCEPT X だと数字用の箱だから文字は弾かれる。だが「=」も扱いたいとなると、箱を Y(文字用)にしたらどうだ?
な)ほ?でも同じじゃないんすか?Y は文字用の箱なんだし…。
文字で受けて、あとで判断する
係)X は数字専用だが、Y は「文字用」だから数字だろうが記号だろうが、なんでも入るだろう? だとしたらどうなる?
な)ふむむぅ…
X じゃないんだから、とりあえず Y に入れるだとは思うんですけど……あ、そういえば昔、文字を数字に変換するとか、スピリチュアルなこと言ってたような?
係)COBOLのどこにスピリチュアルな要素があるんだよ⋯
な)ってことは、Yで受け取って…受け取って…?
係)IF使って考えてみろ。
な)IFっすか?
あ、入力があって、Yに=が入ったら終わって合計表示。それ以外だったら、数値に変換して、TOTALに足していって、次の入力を待つってことでどうです?
係)いいな。
ACCEPTは「受け取るだけ」で判断しない
係) ACCEPTは「ただ受けるだけ」で、判定は必ずIFでやるってことだ。
な)なかなかにおつな感じですなぁ。
あ、でも=以外の文字が入ったら問題になりません?アルファベットとかLOVEとか。
係)誰がLOVEなんて入れるんだよ!
しかし、お前のくせに察しが良いな。
な)どんな悪口!?
係)例えば、数字ではなく「A」とかが入力されたときということだな。
MOVE FUNCTION NUMVAL(Y) TO X
このようにして、Yに入れた文字を数字に変換してXに入れるわけだが、
Y = "5" → OK Y = "=" → IFで弾く Y = "A" → ??? (ゴミデータ発生)
NUMVALは便利だが危険な変換
NUMVAL はな、無理やり数字に変換しようとする。だからこそ、アルファベットを入れると0になったりゴミになったり、場合によってはエラー(例外)になる可能性もあるからな。
な)なんてヤンチャ坊主!作った係長の責任ですよ!
係)なんでだよ!
な)だって、子どもの責任は親がとらないと。だから、俺の責任も係長がとれば解決?
係)いつから俺の子になってんだよ!俺の子だったらお前の暴挙は一切許さねーからな!!
な)ひぃ!
係)だからプログラマーがきちんと制御しろってことだ。つまり、変換する前に「本当に数字かどうか」のチェックが必要だということだ。
次は、ここまでの流れを考えてみろ。
な)あい。
Yに文字が入力された ↓ ・IFで "=" かどうかチェック ・YESなら終了へ ・NOなら、② IFで数字どうかチェック ・YESなら変換へ ・NOなら警告出して入力へ戻る
係)いいだろう。ただ、最後のNO判定のときはループ中になるから、自動的に再入力ということになるな。
な)ふむぅ、これって桁数とかは関係ないもんです?
え、いやまだよくわかってないんですけど、どうやって入れた文字を数字と判断するのかなーって。
0って入れたら0になるんす?123っていれたら123になるもんなんす?
係)こうすることで、可能になるぞ。
MOVE FUNCTION NUMVAL(Y) TO X
例えばこうなる
| 入力(Y) | 結果(X) |
|---|---|
| “0” | 0 |
| “5” | 5 |
| “123” | 123 |
| “001” | 1 |
ということで、処理の順序を再度まとめられるな。
① Y = "=" ? ② Y IS NUMERIC ? ③ NUMVALで変換 ④ TOTALに加算
な)え、IS NUMERICってなんす?ヌメリって…ヌメヌメしてるんすか?なめこっすか?
係)なんでローマ字読みすんだよ…。「イズ・ニューメリック」だよ。
IS NUMERICで「本当に数字か」を確認する
IS NUMERICは「数字かどうかチェック」という命令だ。
使い方としては、
IF Y IS NUMERIC
DISPLAY "数字です"
ELSE
DISPLAY "数字じゃないです"
END-IF
という感じだな。
な)ほー、またおしゃれ構文っすね。サタデー・ナイト・フィーバーっすか。
係)だから、お前のおしゃれ感がわからんっての。
いいから、NUMERICを使って、流れをもう一度整理してみろ。
な)あい!
Yに文字が入力された ↓ IFで = かどうかチェック ・YESなら終了へ ・NOなら、② IF Y IS NUMERIC(数字かどうかチェック) ・YESなら変換へ ・NOなら警告出して入力へ戻る
これでどうでやんしょ?
おむすび
係)ま、良いだろう。
な)まぁ係長の嘘偽りで騙されちゃいましたけど、完全修復してここまできましたからね!
係)なんで俺がいっつも悪者になるんだよ!いいから、ここから形にしていくぞ。
な)承知ングからのガンバリング!
係)…あのな…
係長のワンポイント
ACCEPTは「受け取る」だけで、正しさは保証しない。
だから入力は、必ず 判定 → 変換 → 使用 の順で扱う。NUMVALは便利だが、無理やり変換する“危険な橋”でもある。IS NUMERICで事前に弾いて初めて、安全な処理になる。
COBOLは入力を信用しない──プログラマが責任を持って検証する言語だ。


コメント