文字の長さ
問題
続いて文字の長さについて。6つの言語で「あ」の長さを取得してみました。しかし、やはり1つだけ出力結果が違うものがありました。それはどれでしょうか?
それぞれ、ソースファイルの文字コードやコンパイルオプションなどは正しく設定されているハズなのですが…。
program Project1; {$APPTYPE CONSOLE} var str: WideString; begin str := 'あ'; Write(Length(str)); end.
#include <iostream> using namespace std; int main(int argc, char* argv[]) { wstring str = L"あ"; cout << str.length(); return 0; }
package project1; public class Project1 { public static void main(String[] args) { String str = "あ"; System.out.print(str.length()); } }
namespace project1 { public class Project1 { public static void Main() { string str = "あ"; System.Console.Write(str.Length); } } }
<?php ini_set('mbstring.internal_encoding', 'UTF-8'); $str = 'あ'; echo mb_strlen($str); ?>
$KCODE='u' str = 'あ' print str.length
解説
正解は「Ruby」。
Rubyでは、期待した「1」ではなく「3」が出力されます。それ以外の言語では正しく「1」が出力されます。Delphi/C++/Java/C#では基本的に1文字を16bitのUnicodeで管理することが可能です。特にうっかりミスを起こすことはないでしょう。
PHPでは、文字を処理する際のエンコード(UTF-8やSJISなど)を設定することができます。問題のコードでは、UTF-8でエンコードされた「あ」をmb_strlen関数を利用して正しく1文字として認識しています。しかし、Rubyでは文字列の長さを取得するlengthメソッドはUTF-8に対応しておらず、バイト単位のサイズが返されます。そのため「3」が出力されました。
そこでRubyでは、以下に示すコードのようにUTF-8に対応したライブラリ「jcode」または「RailsのActiveSupport」を利用することで正しく「1」が出力されます。
require 'jcode' $KCODE='u' str = 'あ' print str.jlength
require 'rubygems' require 'active_support' $KCODE='u' str = 'あ' print str.chars.length