- 締切済み
perlの制御文について
汚くて申し訳ありません。 以下のようなperlのプログラムを組んだのですが制御文が思い通りに動きません。 比較対象の数字の先頭の0を取れば正常に動くのですがどうしても0をはずすことはできないのです。 いろいろ試してみたのですがどうしてもうまきかないので知恵を貸してください。 $input = <STDIN>; if($input > 0130){ print "A\n"; } elsif(($input > 0120)&&($input < 0130)){ print "B\n"; } else{ print "C\n"; }
- みんなの回答 (9)
- 専門家の回答
みんなの回答
- _--_--_-_-
- ベストアンサー率47% (8/17)
1 つ補足させていただきます。文字列の比較演算子について。 以上は ge, 以下は le, より大きいは gt, より小さいは lt です。 目的に応じてお使い分け下さい。 先程の私の回答では、質問文のプログラムに則ってこれらの演算子をチョイスさせていただきました。 もし意図と異なる場合は、gt を ge に変えてみてください。 ご参考までに数値の比較演算子との比較表: < lt > gt <= le >= ge <=> cmp
- _--_--_-_-
- ベストアンサー率47% (8/17)
Perl では、0 から始まる数字は八進数として扱われます。 したがって、0130 は十進数の 88 として扱われます。 $input > 0130 というのは、$input が 88 より大きいかどうかを判定していることになります。 しかし、日常生活において 0130 と言えば、通常は単に 130 のことを指しますね。 ここで曖昧性が生じます。 質問者様が仰っている「0130」とは、十進数の 88 のことですか ? それとも、十進数の 130 のことですか ? そこを明確にする必要があります。 まあ、それはひとまず置いておきましょう。 ところで、質問文にあるプログラムには $input = <STDIN>; とユーザの入力を求める部分がありますね。 ここで例えば「0130」などと入力しても、$input に代入されるのは「0130」にはなりません。 それはなぜか ? 入力する場面を考えてみてください。 「0130」とキーボードをタイプします。しかし、それだけでは入力したことにはなりません。そう、最後に「ENTER」キーを押下しなければなりません。 実は、$input に代入されるのは "0130\n" になります。 「0130」+ 改行です。ENTER キーを押すと、改行も入力されてしまうということですね。 そこで、この不要な改行を削除する処理を行います。 やり方は簡単で: $input = <STDIN>; chomp $input; たったこれだけです。 chomp という、末尾の改行を削除してくれる魔法の関数を使います (より厳密には末尾の $/ を削除する)。 さて、話を戻しましょう。 > 比較対象の数字の先頭の 0 を取れば正常に動くのですが さきほど私は「曖昧」と言いましたが、よくよく質問者様の仰ることを吟味すると、どうも 0130 というのは十進数の 130 のことのようですね。 私の読解力不足でした。大変申し訳ありません。 以下に結論を示します: $input = <STDIN>; chomp $input; if ($input gt '0130') { print "A\n"; } elsif ($input gt '0120' and $input lt '0130') { print "B\n"; } else { print "C\n"; } しかし、私ならばこんな回りくどい書き方はしません。 以下のように書くでしょう: defined ($input = <>) or exit; chomp $input; local $\ = "\n"; print $input gt '0130' ? 'A' : $input gt '0120' && $input lt '0130' ? 'B' : 'C';
- kumoz
- ベストアンサー率64% (120/185)
$input の評価が不足してしまっているので、もう1度 eval で評価してやると うまくいくと思います。 chomp($input = <STDIN>); if (eval($input) > 0130) { print "A\n"; } elsif ((eval($input) > 0120) && (eval($input) < 130)) { print "B\n"; } else { print "C\n"; }
- sakusaker7
- ベストアンサー率62% (800/1280)
文字列比較で行う例が出たので use strict; use warnings; use feature ':5.10'; #$input = <STDIN>; while (my $input = <DATA>) { chomp $input; print "$input => "; if ($input >= 130){ say 'A'; } elsif (($input >= 120) && ($input < 130)){ say 'B'; } else { say 'C'; } } __END__ 0099 0100 0129 0130 0131 0119 0120 0121 0140 AAAA 00130 文字列→数値への変換はPerlがよろしくやってくれます。 0099 => C 0100 => C 0129 => B 0130 => A 0131 => A 0119 => C 0120 => B 0121 => B 0140 => A Argument "AAAA" isn't numeric in numeric ge (>=) at hoge.pl line 9, <DATA> line 10. AAAA => C 00130 => A こんな感じ。
- tatsu99
- ベストアンサー率52% (391/751)
#4です。 条件1 0130以上ならA 条件2 0120以上0130未満ならB 条件3 それ以外ならC が正しい仕様だとすると #4の内容を以下のように変更してください if($input gt '0130'){ を if($input ge '0130'){ に変更 elsif(($input gt '0120')&&($input lt '0130')){ を elsif(($input ge '0120')&&($input lt '0130')){ に変更 質問で提示された if($input > 0130){ elsif(($input > 0120)&&($input < 0130)){ をそのまま、文字の比較に置き換えていました。 上記は、本来は if($input >= 0130){ elsif(($input >= 0120)&&($input < 0130)){ ですね。
- tatsu99
- ベストアンサー率52% (391/751)
数値として比較ではなく、文字列として比較されてはいかがですか。 以下のスクリプトを実行してみてください。 $input = <STDIN>; chomp ($input); #最後に改行があるのでそれをとる。 if($input gt '0130'){ print "A\n"; } elsif(($input gt '0120')&&($input lt '0130')){ print "B\n"; } else{ print "C\n"; }
- sakusaker7
- ベストアンサー率62% (800/1280)
質問にある例だと、0120とか0130は数値として評価されますから 八進数で表記されていることになりますよ? (十進数での)数値として120とか130にしたいのなら0をつけてはいけません。 入力データが文字列で、先頭に0がついてるようなものであっても 適当に変換してくれるので問題ないはずですが。 うまくいかないという動作例をだしてもらえますか?
先頭の0があることで文字列として認識されているのでしょうね 0を処理すればよいのでしょうが、 0が必要な目的がわからないため適切な処理方法もわかりません
- tatsu99
- ベストアンサー率52% (391/751)
プログラムは、どのような値を入力すると、 どのような結果がでることを期待しているのでしょうか? つまり、なにがどうなれば、正常で、何がどうなるとだめなのでしょうか?
補足
分かりにくくすみません 制御文をうまく動かしたいだけなんです 最初の入力で例えば0121と入力するとBが出力されるように組んだつもりなのですがAが出力されてしまうのです 条件1 0130以上ならA 条件2 0120以上0130未満ならB 条件3 それ以外ならC という制御をしたいのです