アプリ版:「スタンプのみでお礼する」機能のリリースについて

汚くて申し訳ありません。
以下のようなperlのプログラムを組んだのですが制御文が思い通りに動きません。
比較対象の数字の先頭の0を取れば正常に動くのですがどうしても0をはずすことはできないのです。
いろいろ試してみたのですがどうしてもうまきかないので知恵を貸してください。

$input = <STDIN>;
if($input > 0130){
print "A\n";
}
elsif(($input > 0120)&&($input < 0130)){
print "B\n";
}
else{
print "C\n";
}

A 回答 (9件)

プログラムは、どのような値を入力すると、


どのような結果がでることを期待しているのでしょうか?
つまり、なにがどうなれば、正常で、何がどうなるとだめなのでしょうか?

この回答への補足

分かりにくくすみません
制御文をうまく動かしたいだけなんです

最初の入力で例えば0121と入力するとBが出力されるように組んだつもりなのですがAが出力されてしまうのです

条件1 0130以上ならA
条件2 0120以上0130未満ならB
条件3 それ以外ならC

という制御をしたいのです

補足日時:2008/10/18 12:11
    • good
    • 0

先頭の0があることで文字列として認識されているのでしょうね


0を処理すればよいのでしょうが、
0が必要な目的がわからないため適切な処理方法もわかりません
    • good
    • 0

質問にある例だと、0120とか0130は数値として評価されますから


八進数で表記されていることになりますよ?

(十進数での)数値として120とか130にしたいのなら0をつけてはいけません。
入力データが文字列で、先頭に0がついてるようなものであっても
適当に変換してくれるので問題ないはずですが。

うまくいかないという動作例をだしてもらえますか?
    • good
    • 0

数値として比較ではなく、文字列として比較されてはいかがですか。


以下のスクリプトを実行してみてください。
$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";
}
    • good
    • 0

#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)){
ですね。
    • good
    • 0

文字列比較で行う例が出たので



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

こんな感じ。
    • good
    • 0

$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";
}
    • good
    • 0

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';
    • good
    • 0

1 つ補足させていただきます。

文字列の比較演算子について。
以上は ge, 以下は le, より大きいは gt, より小さいは lt です。
目的に応じてお使い分け下さい。
先程の私の回答では、質問文のプログラムに則ってこれらの演算子をチョイスさせていただきました。
もし意図と異なる場合は、gt を ge に変えてみてください。

ご参考までに数値の比較演算子との比較表:
< lt
> gt
<= le
>= ge
<=> cmp
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!