• ベストアンサー

lengthで返ってくるバイト数の計算があいません

お世話になります。 lengthで返ってくるバイト数の計算があわず困っています。 全角文字列と全角スペースをあわせて12文字(24バイト)の出力をさせたくて以下のように記述しました。 $spaceStr = ' ' x ((24 - length($in{'name'}))/2); $in{'name'}には全角の名前が入るようにしています。 最終的に$spaceStrをテキストに出力したいのですが、 例えば$in{'name'}が「あ」の一文字の場合、期待では ' ' x ((24 - 2)/2) なので11文字の全角スペースが出力されると思ったのですが、出力は9文字の18バイト分の全角スペースしか出力されません。 この原因は何でしょうか? ご教授の方をよろしくお願いします。

  • Perl
  • 回答数4
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.4

#2補足>入力"あい"で253832256130253832256132出てきました。 #2補足>これを16進数(から戻す)にすると%82%a0%82%a2になりますが・ ということは、 length($in{$name})している時 $in{$name}="%82%a0%82%a2"; となっているということです。(それなら12バイトは納得ですね。) $value="%82%a0%82%a2"; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; で $value="あい"; になりますから $in{$name}= しているところで、変換された$valueを使っていないか、 $valueを変換しているところをスキップしているような感じですね。 もう一度流れを見直してみるか、 ところどころで、printして確認して見て下さい。

sakuraniku
質問者

お礼

正常に出力されるようになりました。 有難うございました。 >それなら12バイトは納得ですね。 確かにそこは納得できましたが、そもそもの原因はわからないままです。。。 再度全体を確認してみます。 本当にお世話になりました。

その他の回答 (3)

  • Hasty
  • ベストアンサー率73% (19/26)
回答No.3

もしかしてmod_perl環境だったりしませんか? mod_perlではグローバル変数が保持されてしまうので、リクエストの度に%inに次々と値が格納されてしまい、変な動作をしているように見えることがあります。 $in{'name'}の値を表示してみて、過去に入力したデータなども入っているようであればこれが原因だと思いますので、スクリプトの最初で undef %in; とするようにしてみて下さい。

参考URL:
http://www.din.or.jp/~bigstone/cgilab/cgitips/mod_perl1.html
sakuraniku
質問者

補足

回答有難うございます。 一応indef %in;も試してみましたが、変化はありませんでした。 使用しているサーバーの環境はmod_perlではないようです。 以前の値が格納されていることはないようです。 ご助言に感謝いたします。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

#1補足>特におかしなところは無いようですが、 $in{'name'}="あい"; でシフトJISのはずなのに6バイトということであれば、 sub StoH ($){ my $chs = shift; return join("",map(sprintf("%02X", $_),unpack("C*",$chs))); } みたいな感じで print &StoH($in{$name}); してみてどんなコードがでてくるか調べてみたらどうでしょう シフトJISで"あい"なら 82A082A2 になるはずですが。

sakuraniku
質問者

補足

何度もご回答を頂き本当に有難うございます。 上のサブルーチンをお借りして出力させてみたところ、入力"あい"で253832256130253832256132と出てきました。 どこかで10進数になっているらしく、これを16進数にすると%82%a0%82%a2になりますが・・・ どこかで変換ミスがあるのでしょうか。 小さな可能性でもいいので、宜しくお願いします。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

結果から考えると、$in{'name'}が6バイトあるということです。 全角一文字が2バイトというのは、文字コードによっては異なることがありますが、「あ」一文字が6バイトは、ちょっと考えにくいので、他の文字がくっついているのではないかと思います。 ちなみに encodingの指定をちゃんとしてやれば、lengthを使っても全角文字も1文字として数えます。

sakuraniku
質問者

補足

確かにそうなんですよね。 それでいろいろ試してみましたが、例えば、$in{'name'}のバイト数は、「あい」を入力すると12バイト、「あいう」を入力すると18バイト、「12文字」と入力すると20バイトと言うようになりました。 1文字あたり6バイトというわけでもないようで… $in{'name'}の中身はS-JISなので、S-JISのまま文字数カウントしてもEUCに変換して文字数カウントしても、おかしなことになりました。 そもそも$in{'name'}にはフォームから受け取った値が入るので、そこに問題があるのかなと思って考えたのですが、以下の書き方におかしな点がありますでしょうか? sub decode_form{ @pairs = split(/&/,$buffer); foreach $pair (@pairs) { ($name,$value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; $name =~ tr/+/ /; $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; &jcode'convert(*value,'sjis'); #同じname属性の場合 if($in{$name} ne ''){ $in{$name} .= " ".$value; }else{ $in{$name} = $value; } } }

関連するQ&A

  • 入力された文字列のバイト数を知りたい。

    こんにちは。 いまWebページ上のテキストボックスに入力されたテキスト文字列のバイト長を判定しようとして, 下記のようなコーディングをしました。 ~ n = escape(document.forms(0).txtProjectCode.value); if (!(n.length == 5)) ~ ところが上記のコーディングだと半角文字は正しくバイト長が取れるのですが,全角文字が入力されると正しくバイト長が取れません。 そうすれば全角文字が入力されても正しくバイト長が取れるでしょうか? 教えてください。よろしくお願いします。

  • LENGTH関数

    こんばんわ! オラクルマスターシルバーに向けて勉強中です! 以前も質問しました。 http://oshiete1.goo.ne.jp/kotaeru.php3?q=481071 さて、また翔泳社のオルクルマスター教科書Silverの中の記述について質問があります。 LENGTH関数の使い方について、 LENGTH(NAME) NAME='オラクルマスター'の時、NAMEがVARCHAR2(20)の時は、結果は8、CAHR(20)の時は結果は12とあります。 CHAR型は、指定したバイト吸うに満たない場合は1バイトの空白文字を埋める、とあるので、8文字+1バイトで答えは9じゃないんですか? 正しい答えは8+4=12となってますが、なんで4なんでしょう?? この4はどこから出てきたのでしょう? どなたか教えてください!よろしくお願いします!

  • バイト数

    こんにちわ。 VB6でのすごく初歩的な質問なんですが、テキストボックスの中の文字のバイト数をLenB関数で取得して表示させようとしたのですが、半角も全角も1文字2バイトとでてしまいますがなぜでしょうか? お暇なときで結構ですのでどなたか回答をおねがいします。

  • 半角と全角が混ざった文字列のバイト処理に関して

    失礼します。 "あイウエお"という文字列があったとして、 出力する場所に6バイト分の幅しかない場合、 "あイウエお"だと7バイトになってしまい入らないので "あイウエ"だけ抜き出して出力し、 2行目に"お"と出力するにはどのような記述をすれば良いのでしょうか?全角の文字を途切らせないで、入りきれないなら次行に移したいのです。 http://oshiete1.goo.ne.jp/kotaeru.php3?q=172521 に載ってるソースを参考にしてみたのですが、上手くいきませんでした。。

  • 見えないバイト数

    見えないバイト数がいます。 何か原因わかりませんでしょうか? とあるプログラムから取得した文字列を print関数を使ってブラウザに出力しました。  print "$AAAA"; この出力された文字列をブラウザからコピーし、 同一プログラム内に$BBBBという変数で定義します。  $BBBB = "コピーしてきた文字列"; ここで$AAAAと$BBBBは同じもののはずなのですが、 if 関数で比較するとなぜかFALSEが返ります・・・。  if($AAAA == $BBBB){   print "AAAAとBBBBは同じです。"; //←こっちが出力されてほしい  } else {   print "AAAAとBBBBは違います。"; //←こっちが出力される  } 文字列のバイト数を調べる「strlen」関数を使用すると、 AAAAが69バイト、BBBBが61バイトと 8バイトの差があります。 どちらを(printで)出力しても目には見えないので 困っております・・・。 なにか心当たり、解決策をご存じの方いらっしゃいませんでしょうか?? ちなみにAAAAとBBBBは、 半角英数+記号(&%/?)で構成されています。

    • ベストアンサー
    • PHP
  • PHPにおいて16進数のアスキー文字とユニコード

    文字列の明確な違いがわかりません。 たとえば16進数のアスキー文字であれば print "\x41"; とした場合  A という文字が出力されます。 また print 0x41; とした場合はアスキー文字ではなく 65という10進数における数値が出力されますね。 さらには print "\xe6\x96\x87\xe5\xad\x97\xe5\x88\x97"; と記述すると 文字列 という文字が出力されます。 ではそうではなくユニコード文字列というのはなんなのでしょうか? 一般てきに \u0000 という形式で表記される物ですが、コレがいまいちわかりません。 これは16進数のアスキー文字によるマルチバイト文字の再現と何がことなるのでしょうか? たとえば、JSONなんかを単純に出力してみるとこのユニコード文字列という形式で表現されますよね? このユニコード文字列の実態?を知りたいです。 よろしく御願いします。

    • ベストアンサー
    • PHP
  • awkでバイト数を方法

    文字列$2を300文字まで切り取る方法は substr($2,1,300)ですが、 全角半角が混在している文字列を 先頭から300バイト取得する方法が分かりません。 お手数をおかけしますが、 ご教授願いします。

  • Excelでバイト数の最大数が決まったデータを作りたいんです!

    上手く説明出来ないんですが・・。 エクセルで、項目それぞれにバイト数の最大数が決まったデータを作りたいんです。 例えば ◆職員番号・・・バイト数12(半角)         職員番号は8桁なので、その後ろに残り12バイトまでの半角パディング。 ◆氏名 ・・・ バイト数16(全角8字まで)         全角8文字以内なら、その後ろに残り8文字までの全角パディング。         全角8文字を超す氏名なら、8文字で切る。 ◆カナ ・・・ バイト数58(半角)         半角カナ文字で残りの58バイトまで半角パディング。 *これをcsvに変換します! これを文字列だけ打ち込んだら、自動で最大バイト数まで半角・全角を埋めるようにすることは出来るでしょうか? また、氏名のところのように自動で8文字までの入力しか出来なくするようにすることは出来るでしょうか? 説明が下手で申し訳ないんですが、おわかりになる方ご教授下さい。 よろしくお願いします!!

  • エクセル:文字列のバイト数が欲しい

    セルB1に、  半角スペース、全角2文字、半角スペース、 と入力しました。 このシートの別のセルに、 =Len(B1)と入力すると4と表示され、 =LenB(B1)と入力すると6と表示されますので、 間違いなく「半角スペース・全角2文字・半角スペース」がB1に入っているはずです。 このシートのコードに、 Private Sub Worksheet_Change(ByVal Target As Range)   If Target.Address = "$L$1" Then     MsgBox LenB(Cells(1, 2).Value)   End If End Sub と打ちました。 ここでシート上のセルL1に何か入力するとメッセージボックスが出るのですが、 メッセージボックスに出る値は8です。 何が原因でしょうか。 6が表示されて欲しいのですが(文字列のバイト数が欲しい)、 どのようにコードを書けばよいでしょうか。 実際にB1に入れていた文字は、 1B です。 (半角スペース・全角数字1・全角英字B・半角スペース)

  • 入力文字のバイト数

    いつも参考にしております。 入力文字のバイト数のカウントについて質問をさせていただきます。 入力フォームなどで、入力文字数の制限をしたいと考えております。 文字を入力するたびに、バイト数がテキストボックスに常に 表示されるようにしたいと考えております。 以下を参考にできるのではないとか思っておりますが。 <script language="javascript"> <!-- function check() {  txt = document.myFORM.myTEXT.value;  n = txt.length;  if (n > 10) alert("10文字以内にしてください"); } --> </script> <form name="myFORM"> <textarea rows="3" name="myTEXT" onChange="check()"></textarea> </form> ご教授お願いいたします。