あなたの天然記念物
ホーム更新雑談Perl鉄ゲタランドナーコースガイド自転車Linuxリンク経歴連絡先

Perlのwriteに漢字を入れる (2016.03.19)

背景

Perlを使い始めて10年以上経ちますけれど、初めてwriteを使おうとして漢字出力に失敗したので。 あと、この件は検索で見つけられず、これまで様々なブログを参考にして来ましたから、その恩返しという意図もあります。

writeは書式付き出力

大抵の出力はprintで差し支えありませんけれど書式付きはwriteで行います。 1行のフォーマットを決めて、左詰、中央、右詰、数値とかのフィールドと埋め込み参照用の変数を指定します。 詳細はPerlの組み込み関数 write の翻訳 - perldoc.jpをご覧ください。

出力例

こんな感じに出力してくれます。
書式付き出力の例

コード


#!/usr/local/bin/perl -w

use 5.10.1;
# スクリプトの文字コードはUTF-8
use utf8;
use strict;
use warnings;

# ファイルの文字コード
use open IO => ":utf8";

use Encode;
use Encode::Locale;

$| = 1;

# コンソール出力の文字コード
binmode STDOUT, ":encoding(console_out)";

# 罫線
my $hear_line = "―――――――――――――\n";

# 書き出しバッファ
my $write_buff;

# 出力先は変数
if (open WB, ">", \$write_buff) {
	# 文字コード無変換を指定
	binmode WB;

	# formatでリテラルの漢字不可、変数で埋め込む
	my $sp = " "; # ←全角空白(デモなので)
	my $sp_locale = Encode::encode locale => $sp;

	# formatの_TOP(ヘッダ)はリテラルの漢字不可
	print WB Encode::encode locale =>
$hear_line .
"番号${sp}タイトル\n";

	my $form_number;
	my $form_title;
	# 変数で漢字入り固定文字列を埋め込む
	format WB =
@###@<@<<<<<<<<<<<<<<<<<<<
$form_number, $sp_locale, $form_title
.

	$form_number = 0;
	for (qw/ルカルカ★ナイトフィーバー たこルカぽっぴっぽー まぐろたべたい/) {
		# 数値はそのまま
		$form_number++;

		# 文字列は文字コード変換
		$form_title = Encode::encode locale => $_;

		write WB;
	}

	# フッタを出力(perlにフッタ用formatは無い)
	print WB Encode::encode locale => $hear_line;

	close WB;

	# バッファに文字コードがlocale(win→cp932、linux→?)で書込済
}

# Perlの文字コードに変換、改行毎にループ(ループ変数に改行なし)
for (split /\n/, Encode::decode locale => $write_buff) {
	# 文字コード(console_out)に変換、コンソールへ出力
	print "$_\n";
}

exit;