- 締切済み
このperlのおかしい所を教えて下さい
下記のプログラムはname11という変数名の文字列の平仮名を指定の数字に変更し、1文字づつ変数に当てはめ、1桁になるまで分解して足していくというプログラムを書きたいのですが、エラーばかりです。 初心者なのでネットの情報を見ながらの作成です。 ご教示よろしくお願いします。 while(($name11)=each %in){ $name11=~s/"ぁ"/6/g; $name11=~s/"あ"/6/g; $name11=~s/"ぃ"/9/g; $name11=~s/"い"/9/g; $name11=~s/"ぅ"/1/g; $name11=~s/"う"/1/g; $name11=~s/"ぇ"/11/; $name11=~s/"え"/11/g; $name11=~s/"ぉ"/3/g; $name11=~s/"お"/3/g; $name11=~s/"か"/6/g; $name11=~s/"が"/6/g; $name11=~s/"き"/9/g; $name11=~s/"ぎ"/9/g; $name11=~s/"く"/1/g; $name11=~s/"ぐ"/1/g; $name11=~s/"け"/11/g; $name11=~s/"げ"/11/g; $name11=~s/"こ"/3/g; $name11=~s/"ご"/3/g; $name11=~s/"さ"/6/g; $name11=~s/"ざ"/6/g; $name11=~s/"し"/9/g; $name11=~s/"じ"/9/g; $name11=~s/"す"/1/g; $name11=~s/"ず"/1/g; $name11=~s/"せ"/11/g; $name11=~s/"ぜ"/11/g; $name11=~s/"そ"/3/g; $name11=~s/"ぞ"/3/g; $name11=~s/"た"/6/g; $name11=~s/"だ"/6/g; $name11=~s/"ち"/9/g; $name11=~s/"ぢ"/9/g; $name11=~s/"っ"/1/g; $name11=~s/"つ"/1/g; $name11=~s/"づ"/1/g; $name11=~s/"て"/11/g; $name11=~s/"で"/11/g; $name11=~s/"と"/3/g; $name11=~s/"ど"/3/g; $name11=~s/"な"/6/g; $name11=~s/"に"/9/g; $name11=~s/"ぬ"/1/g; $name11=~s/"ね"/11/; $name11=~s/"の"/3/g; $name11=~s/"は"/6/g; $name11=~s/"ば"/6/g; $name11=~s/"ぱ"/6/g; $name11=~s/"ひ"/9/g; $name11=~s/"び"/9/g; $name11=~s/"ぴ"/9/g; $name11=~s/"ふ"/1/g; $name11=~s/"ぶ"/1/g; $name11=~s/"ぷ"/1/g; $name11=~s/"へ"/11/g; $name11=~s/"べ"/11/g; $name11=~s/"ぺ"/11/g; $name11=~s/"ほ"/3/g; $name11=~s/"ぼ"/3/g; $name11=~s/"ぽ"/3/g; $name11=~s/"ま"/6/g; $name11=~s/"み"/9/g; $name11=~s/"む"/1/g; $name11=~s/"め"/11/g; $name11=~s/"も"/3/g; $name11=~s/"ゃ"/6/g; $name11=~s/"や"/6/g; $name11=~s/"ゅ"/1/g; $name11=~s/"ゆ"/1/g; $name11=~s/"ょ"/3/g; $name11=~s/"よ"/3/g; $name11=~s/"ら"/6/g; $name11=~s/"り"/9/g; $name11=~s/"る"/1/g; $name11=~s/"れ"/11/g; $name11=~s/"ろ"/3/g; $name11=~s/"ゎ"/6/g; $name11=~s/"わ"/6/g; $name11=~s/"ゐ"/9/g; $name11=~s/"ゑ"/11/g; $name11=~s/"を"/3/g; $name11=~s/"ん"/1/g; } substr($name11, 0, 1) = $a; substr($name11, 1, 2) = $b; substr($name11, 2, 3) = $c; substr($name11, 3, 4) = $d; substr($name11, 4, 5) = $e; substr($name11, 5, 6) = $f; substr($name11, 6, 7) = $g; substr($name11, 7, 8) = $h; substr($name11, 9, 10) = $i; $x = $a + $b + $c + $d + $e + $f + $g + $h + $i; while ($x > 10) { substr($x, 0, 1) = $a; substr($x, 1, 2) = $b; substr($x, 2, 3) = $c; substr($x, 3, 4) = $d; substr($x, 4, 5) = $e; substr($x, 5, 6) = $f; substr($x, 6, 7) = $g; substr($x, 7, 8) = $h; substr($x, 9, 10) = $i; $x = $a + $b + $c + $d + $e + $f + $g + $h + $i; }
- みんなの回答 (10)
- 専門家の回答
みんなの回答
- kuroizell
- ベストアンサー率55% (95/170)
自分用メモを兼ねて、総まとめ。 #!/usr/local/bin/perl use strict; use warnings; use utf8; binmode STDIN, ":utf8"; binmode STDOUT, ":utf8"; open (FILE, "<:utf8","./list.txt"); my @input = <FILE>; close FILE; my %table = ( 'あ' => 1, 'ぁ' => 1, 'か' => 1, 'が' => 1, 'さ' => 1, 'ざ' => 1, 'た' => 1, 'だ' => 1, 'な' => 1, 'は' => 1, 'ば' => 1, 'ま' => 1, 'や' => 1, 'ゃ' => 1, 'ら' => 1, 'わ' => 1, 'い' => 2, 'ぃ' => 2, 'き' => 2, 'ぎ' => 2, 'し' => 2, 'じ' => 2, 'ち' => 2, 'ぢ' => 2, 'に' => 2, 'ひ' => 2, 'び' => 2, 'み' => 2, 'ゐ' => 2, 'り' => 2, 'う' => 3, 'ぅ' => 3, 'く' => 3, 'ぐ' => 3, 'す' => 3, 'ず' => 3, 'つ' => 3, 'っ' => 3, 'づ' => 3, 'ぬ' => 3, 'ふ' => 3, 'ぶ' => 3, 'む' => 3, 'ゆ' => 3, 'ゅ' => 3, 'る' => 3, 'ん' => 3, 'え' => 4, 'ぇ' => 4, 'け' => 4, 'げ' => 4, 'せ' => 4, 'ぜ' => 4, 'て' => 4, 'で' => 4, 'ね' => 4, 'へ' => 4, 'べ' => 4, 'め' => 4, 'ゑ' => 4, 'れ' => 4, 'お' => 5, 'ぉ' => 5, 'こ' => 5, 'ご' => 5, 'そ' => 5, 'ぞ' => 5, 'と' => 5, 'ど' => 5, 'の' => 5, 'ほ' => 5, 'ぼ' => 5, 'も' => 5, 'よ' => 5, 'ょ' => 5, 'ろ' => 5, 'を' => 5, ); my $anser; foreach my $input(@input){ print "入力文字列 = $input"; foreach my $num(split //,$input){ $anser = ($anser + $table{$num}) % 9; } if($anser == 0){ print "解答 = 9\n";} else{ print "解答 = $anser\n";} $anser = 0; }
- kuroizell
- ベストアンサー率55% (95/170)
>しかし、なぜか『あ』と打つと『11』が返ってきますね・・・。 >なぜだろう!? 文字コードの問題です。 明確にUTF-8で処理されるようにしないとダメなようです。 プログラムとname11.txtをUTF-8で保存し、以下のようにすることで解決できました。 use utf8; binmode STDIN, ":utf8"; binmode STDOUT, ":utf8"; open (FILE, "<:utf8","./name11.txt");
- Tacosan
- ベストアンサー率23% (3656/15482)
途中経過を省略していいなら, #5 のハッシュをベースにして my $total; foreach my $char (@chars) { $total = ($total + $table{$char}) % 9; } $total = 9 if $total == 0 && @chars; が最も簡単な気がする.
- kuroizell
- ベストアンサー率55% (95/170)
自分の勉強の課題としてやってたので、とりあえずの完成コードを。 sakusaker7さんを大いに参考にさせて頂きました。 相変わらずマルチバイト処理の問題は解決できていませんし、 元の文字列が長いと、数値に狂いが出ますが、とりあえず・・・・。 #!/usr/local/bin/perl use strict; use warnings; open FILE,"./name11.txt"; my @input = <FILE>; close FILE; foreach my $numbers(@input){ print "元の文字列 = $numbers"; $numbers =~ s/[あぁかがさざただなはばまやゃらわ]/1/g; $numbers =~ s/[いぃきぎしじちぢにひびみゐり]/2/g; $numbers =~ s/[うぅくぐすずつっづぬふぶむゆゅるん]/3/g; $numbers =~ s/[えぇけげせぜてでねへべめゑれ]/4/g; $numbers =~ s/[おぉこごそぞとどのほぼもよょろを]/5/g; print "数字(文字列) = $numbers"; $numbers = sprintf("%f",$numbers); print "数字(数値) = $numbers\n"; while ($numbers > 9){ my $int = $numbers; $numbers = 0; foreach my $x(my @int = split //,$int){ $numbers += $x; } } print "解答の一桁 = $numbers\n\n"; }
- sakusaker7
- ベストアンサー率62% (800/1280)
わからないことがあったら適当に訊いてください。 答えられる範囲で答えます。 とはいえできれば、「実はこういう仕様だったのでここをこうなるように修正してください」 というのはご勘弁を :)
お礼
かなり勉強になりました。 ありがとうございます!
- sakusaker7
- ベストアンサー率62% (800/1280)
こういう計算をするのをつくりたいということなんでしょうか? 11の扱いが微妙だけどとりあえず。 #!/usr/bin/perl # -*- coding: utf8 -* use strict; use warnings; use feature ':5.10'; use utf8; my %table = ( "ゅ" => 1, "ゆ" => 1, "る" => 1, "ぅ" => 1, "う" => 1, "く" => 1, "ぐ" => 1, "す" => 1, "ず" => 1, "っ" => 1, "つ" => 1, "づ" => 1, "ぬ" => 1, "ふ" => 1, "ぶ" => 1, "ぷ" => 1, "む" => 1, "ん" => 1, "ね" => 11, "て" => 11, "で" => 11, "せ" => 11, "ぜ" => 11, "れ" => 11, "ゑ" => 11, "ぇ" => 11, "え" => 11, "け" => 11, "げ" => 11, "へ" => 11, "べ" => 11, "ぺ" => 11, "め" => 11, "こ" => 3, "ご" => 3, "そ" => 3, "ぞ" => 3, "ぉ" => 3, "お" => 3, "と" => 3, "ど" => 3, "の" => 3, "ほ" => 3, "ぼ" => 3, "ぽ" => 3, "も" => 3, "ょ" => 3, "ろ" => 3, "を" => 3, "よ" => 3, "か" => 6, "が" => 6, "ぁ" => 6, "あ" => 6, "さ" => 6, "ざ" => 6, "た" => 6, "だ" => 6, "な" => 6, "は" => 6, "ば" => 6, "ぱ" => 6, "ま" => 6, "ゃ" => 6, "や" => 6, "ゎ" => 6, "ら" => 6, "わ" => 6, "き" => 9, "ぎ" => 9, "ぃ" => 9, "い" => 9, "し" => 9, "じ" => 9, "ち" => 9, "ぢ" => 9, "に" => 9, "ひ" => 9, "び" => 9, "ぴ" => 9, "み" => 9, "り" => 9, "ゐ" => 9 ); my $input_string = "ほんじつはせいてんなり"; my @chars = split //, $input_string; say join(':', @chars); my $total; foreach my $char (@chars) { $total += $table{$char}; } say $total; while ($total > 9) { my $s = '' . $total; $total = 0; foreach my $digit (split //, $s) { $total += $digit; } say $total; } say $total; >perl moge.pl | nkf -s Wide character in print at moge.pl line 102. ほ:ん:じ:つ:は:せ:い:て:ん:な:り 67 13 4 4 とりあえずの例なので、警告とかは気にしないでください。
お礼
いや~凄いですね! パッと見でも僕のと全く違いますね。。。 それぞれの関数などの意味を調べて勉強します。 本当、ありがとうございます!
- sakusaker7
- ベストアンサー率62% (800/1280)
こういうことですか? こんにちは ← 入力 → 31996 → 3 + 1 + 9 + 9 + 6 → 28 → 2 + 8 → 10 → 1 + 0 → 1 ← 結果 あと、参考までに使っているPerlのバージョンがわかるなら教えてください。
お礼
そうです!!まさに、そうです!!! バージョンは確認しようとしてできなかったのですが、1週間前の時点で最新のやつでした。
- kuroizell
- ベストアンサー率55% (95/170)
Perl勉強中の者です。 プログラム系は本当に全くダメなのですが、その分、有識者がまともじゃないと首をひねるスクリプトの中身が理解できます。 (というか、まるで自分が書いたかのような内容です) 解決はできませんが、一部だけでもご参考までに。 #入力の$name11は、name.txtというファイルから読み込んでみました open FILE,"./name.txt"; foreach(<FILE>){ print; s/[あぁかがさざただなはばまやゃらわ]/1/g; s/[いぃきぎしじちぢにひびみゐり]/2/g; s/[うぅくぐすずつっづぬふぶむゆゅるん]/3/g; s/[えぇけげせぜてでねへべめゑれ]/4/g; s/[おぉこごそぞとどのほぼもよょろを]/5/g; print; foreach (my @num = split //,){ print; print "\n"; } } Perlらしく、変数は省略しています。 何度もprintしてるは、単に置換前後の結果を見比べるためですので不要です。 マルチバイトから1バイトへの置換は上手くいかないので、UTF8にEncodeするなどの必要もあります。 あとは足し算して、一桁になるまで繰り返す部分でしょうか。 私にできるのは現時点ではここまでです。
お礼
ありがとうございます。 なるほど、こんな書き方もあるのですね。 勉強になります。
- sakusaker7
- ベストアンサー率62% (800/1280)
%in って名前のハッシュを使っているところからするとCGIなのかなあ。 とりあえず、どういう入力があって、どういう結果が得たいのかという 情報があったほうがアドバイスもしやすいと思います。 まともじゃないスクリプトだけ見せられても首捻るだけです。 それでも気になった点を書いておくと、 ・置換のときに各ひらがながことごとくダブルクォートでくくられているのは 何か勘違いしているような気がする。 ・$aから$iまでの変数について、代入されていないのにその値を別の変数に代入している。 substrでいったい何をやろうとしているのかは見当もつきません。
お礼
CGIです! name11には文字列が入って送られてきます。 それを1文字づつ分解し、数字に変え、全部足して、また分解して、、 を繰り返して1ケタになるまで計算したいんです。
- Tacosan
- ベストアンサー率23% (3656/15482)
「エラーばかりです」というなら, どのようなエラーが出ているのかを一字一句そのままで書いてください. この while で何をしたいの?
お礼
ありがとうございます。 ページが表示できません。と出ます。 1234を 1と2と3と4に分けて 1+2+3+4をしたいのです。
お礼
ありがとうございます! まさに作りたいものができそうです。 しかし、なぜか『あ』と打つと『11』が返ってきますね・・・。 なぜだろう!?