• ベストアンサー

printfの書式指定での2バイト文字の巾

2バイト文字、1バイト文字どちらもありうる(構成が不明である)文字列をバイト単位で桁揃えして出力したいのですが、 use encoding 'cp932'; printf "|%2s\n|","あ"; printf "|%2s\n|","aa"; とすると、出力結果は当然 | あ| |aa| となって、桁が揃わないですよね。「バイト単位で2バイト分の巾」という指定を実現するにはどうしたらいいのでしょうか。日本語処理ではよくある問題だと思うのですが。

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

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

ちょっと裏技的に use Encode ; binmode(STDOUT,":bytes") ; # バイトコードをそのまま出力させるように変更 printf "|%2s\n|",Encode::encode('cp932',"あ"); # cp932にencodeすれば、2バイト文字は「2バイト=2文字」扱いになる 既出の方法の方が汎用性はありますけど。

noname#226683
質問者

お礼

とりあえずはこの方法が簡単そうですので採用させていただこうかと思います。 どうもありがとうございました。

その他の回答 (1)

回答No.1

# 表示がくずれるので空白2文字を全角空白にしていることに注意 use strict; use warnings; use utf8; use Encode; use Encode::CJKConstants; my @hello_list = (   'こんにちは、世界!!',     'Hello World!!',   'HELLO WORLD!!', 'こんにちは、World。',   "コンニチハ 世界.", '世界,你好!' ); binmode STDOUT, ":encoding(utf8)"; for my $hello (@hello_list) {   my $view_length = count_view_length($hello);   my $char_length = length $hello;   my $format   = '%-' . ( 32 - ( $view_length - $char_length ) ) . 's :';   printf $format, $hello;   print "\n"; } # result。等幅フォントで見れば : (コロン)が揃っている # こんにちは、世界!!       : # Hello World!!          : # HELLO WORLD!!    : # こんにちは、World。       : # コンニチハ 世界.           : # 世界,你好!           : sub count_view_length {   my $str     = shift;   my $view_length = 0;   for my $char ( split q{}, $str ) {     my $sjis_char = encode( 'sjis', $char );     if ( $char =~ m/\p{InBasicLatin}/ ) {       $view_length += 1;     }     elsif ( $sjis_char =~ m/^$Encode::CJKConstants::RE{SJIS_KANA}$/ ) {       $view_length += 1;     }     else {       $view_length += 2;     }   }   return $view_length; }

noname#226683
質問者

お礼

大変参考になりました。どうもありがとうございました。

関連するQ&A