Hatena::Diary

tacoworks 活動記録

華麗にスナップを利かせて軽やかに orz

そんな暮らしを目指しています。
放置中のサイトtacoworks.jpもどうぞ。

2004 | 01 | 02 | 03 | 04 | 05 | 06 | 08 | 09 | 10 | 11 | 12 |
2005 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2006 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 11 |
 | 

2006-02-07

locale の対応状況調査(その1) このエントリーを含むブックマーク

id:logion:20041222#p1id:logion:20051128#p1 でも書いたようにすげー心待ちにしていていた C++Builder2006J ですが、昨年末バージョンアップ版が届きました。年明けの Update1 も当てて移行の準備も万端なはず…なのですが、ちょっと気になる点があってまだ移行していませんでした。

それは、C++Builder6J の頃から気になっていた文字列の処理についてです。

パスファイル名を操作する自作ライブラリにおいて、、それまでは std::string (char) を使っていて、日本語ファイル名の事については(自分自身が使わないという理由で)特に気にしていませんでした。しかし、id:logion:20050706#p1id:logion:20050912 のような事態に遭遇してからはUnicode を使うように宗旨変えし、std::wstring (wchar_t) に書き変えていました。

この Unicode 版の自作ライブラリを C++Builder2006 でコンパイルした所、問題が発生しました。id:logion:20050912 のように std::locale を使うコードは、(C++Builder6J では問題なく動いていましたが) C++Builder2006 ではlocale の生成時に例外が飛んでくるようになっていたのです。

どうも locale 名の "ja_JP.sjis" がマズいらしいのですが、正しい locale 名というものを知りません。試行錯誤でとりあえず "japanese" ではちゃんと生成できていましたが…。

ということで、調べてみました。(長いのでいったん切ります)


調査方法 このエントリーを含むブックマーク

まず locale 名にどのようなものがあるのか全然知らなかったので、google 等でそれっぽい文字列をかき集めて以下を試してみました。

C の場合: このエントリーを含むブックマーク

ロケール文字列bcb6(C++Builder6J)bcb10(C++Builder2006J)vc71(VisualStudio.NET2003)vc8(VisualStudio2005)
ja_JPNULLNULLNULLNULL
ja_JP.SJISNULLNULLNULLNULL
ja_JP.sjisNULLNULLNULLNULL
ja_JP.EUCNULLNULLNULLNULL
ja_JP.eucJPNULLNULLNULLNULL
ja_JP.utf8NULLNULLNULLNULL
japaneseJapanese_Japan.932Japanese_Japan.932Japanese_Japan.932Japanese_Japan.932
japanese_JAPANJapanese_Japan.932Japanese_Japan.932Japanese_Japan.932Japanese_Japan.932
japanese_JAPAN.932Japanese_Japan.932Japanese_Japan.932Japanese_Japan.932Japanese_Japan.932
Japanese_Japan.932Japanese_Japan.932Japanese_Japan.932Japanese_Japan.932Japanese_Japan.932
Japanese_Japan.20932Japanese_Japan.20932Japanese_Japan.20932Japanese_Japan.20932Japanese_Japan.20932
JAPANESE_JAPAN.JA16SJISJapanese_Japan.0Japanese_Japan.0NULLNULL
japanese_Japan.ja16sjisJapanese_Japan.0Japanese_Japan.0NULLNULL
japanese_Japan.ja16eucJapanese_Japan.0Japanese_Japan.0NULLNULL
Japanese_Japan.UTF8Japanese_Japan.0Japanese_Japan.0NULLNULL
ja_JP.eucJPNULLNULLNULLNULL
ja_JP.ujisNULLNULLNULLNULL
ja_JP.EUCNULLNULLNULLNULL
japanese.eucJapanese_Japan.0Japanese_Japan.0NULLNULL
Japanese-EUCJapanese_Japan.932Japanese_Japan.932Japanese_Japan.932NULL
jaNULLNULLJapanese_Japan.932NULL
jpnJapanese_Japan.932Japanese_Japan.932Japanese_Japan.932Japanese_Japan.932
japanNULLNULLJapanese_Japan.932NULL
C-SJISNULLNULLCatalan_Spain.1252NULL
de_DEGerman_Germany.850German_Germany.850NULLNULL
de_DE@euroGerman_Germany.850German_Germany.850NULLNULL
de_DEGerman_Germany.850German_Germany.850NULLNULL
deNULLNULLNULLNULL
geNULLNULLGerman_Germany.1252NULL
en_ENNULLNULLNULLNULL
English_USA.1252NULLNULLEnglish_United States.1252English_United States.1252
French_France.1252French_France.1252French_France.1252French_France.1252French_France.1252
French_Canada.ACPFrench_Canada.0French_Canada.0French_Canada.1252French_Canada.1252
French_Canada.OCPFrench_Canada.0French_Canada.0French_Canada.850French_Canada.850
de_DE.iso88591German_Germany.0German_Germany.0NULLNULL
de_DE.ISO-8859-1German_Germany.0German_Germany.0NULLNULL
chineseChinese_Taiwan.950Chinese_Taiwan.950Chinese_Taiwan.950Chinese_Taiwan.950
chinese-simplifiedChinese_Taiwan.950Chinese_Taiwan.950Chinese_Taiwan.950Chinese_People's Republic of China.936
chinese-traditionalChinese_Taiwan.950Chinese_Taiwan.950Chinese_Taiwan.950Chinese_Taiwan.950
czechCzech_Czech Republic.852Czech_Czech Republic.852Czech_Czech Republic.1250Czech_Czech Republic.1250
danishDanish_Denmark.850Danish_Denmark.850Danish_Denmark.1252Danish_Denmark.1252
dutchDutch_Netherlands.850Dutch_Netherlands.850Dutch_Netherlands.1252Dutch_Netherlands.1252
dutch-belgianDutch_Netherlands.850Dutch_Netherlands.850Dutch_Netherlands.1252Dutch_Belgium.1252
belgianBelarusian_Belarus.866Belarusian_Belarus.866Dutch_Belgium.1252Dutch_Belgium.1252
englishEnglish_United States.437English_United States.437English_United States.1252English_United States.1252
english-ausEnglish_United States.437English_United States.437English_United States.1252English_Australia.1252
australianNULLNULLEnglish_Australia.1252English_Australia.1252
canadianNULLNULLEnglish_Canada.1252English_Canada.1252
english-canEnglish_United States.437English_United States.437English_United States.1252English_Canada.1252
english-nzEnglish_United States.437English_United States.437English_United States.1252English_New Zealand.1252
english-ukEnglish_United States.437English_United States.437English_United States.1252English_United Kingdom.1252
ukNULLNULLUkrainian_Ukraine.1251English_United Kingdom.1252
americanNULLNULLEnglish_United States.1252English_United States.1252
american englishEnglish_United States.437English_United States.437English_United States.1252English_United States.1252
american-englishEnglish_United States.437English_United States.437English_United States.1252English_United States.1252
english-americanEnglish_United States.437English_United States.437English_United States.1252English_United States.1252
english-usEnglish_United States.437English_United States.437English_United States.1252English_United States.1252
english-usaEnglish_United States.437English_United States.437English_United States.1252English_United States.1252
usNULLNULLEnglish_United States.1252English_United States.1252
finnishFinnish_Finland.850Finnish_Finland.850Finnish_Finland.1252Finnish_Finland.1252
frenchFrench_France.850French_France.850French_France.1252French_France.1252
french-belgianFrench_France.850French_France.850French_France.1252French_Belgium.1252
french-canadianFrench_France.850French_France.850French_France.1252French_Canada.1252
french-swissFrench_France.850French_France.850French_France.1252French_Switzerland.1252
germanGerman_Germany.850German_Germany.850German_Germany.1252German_Germany.1252
german-austrianGerman_Germany.850German_Germany.850German_Germany.1252German_Austria.1252
swissNULLNULLGerman_Switzerland.1252German_Switzerland.1252
german-swissGerman_Germany.850German_Germany.850German_Germany.1252German_Switzerland.1252
greekGreek_Greece.737Greek_Greece.737Greek_Greece.1253Greek_Greece.1253
hungarianHungarian_Hungary.852Hungarian_Hungary.852Hungarian_Hungary.1250Hungarian_Hungary.1250
icelandicIcelandic_Iceland.850Icelandic_Iceland.850Icelandic_Iceland.1252Icelandic_Iceland.1252
italianItalian_Italy.850Italian_Italy.850Italian_Italy.1252Italian_Italy.1252
italian-swissItalian_Italy.850Italian_Italy.850Italian_Italy.1252Italian_Switzerland.1252
japaneseJapanese_Japan.932Japanese_Japan.932Japanese_Japan.932Japanese_Japan.932
koreanKorean_Korea.949Korean_Korea.949Korean_Korea.949Korean_Korea.949
norwegianNorwegian (Bokm虱)_Norway.850Norwegian (Bokm虱)_Norway.850Norwegian (Bokm虱)_Norway.1252Norwegian (Bokm虱)_Norway.1252
norwegian-bokmalNorwegian (Bokm虱)_Norway.850Norwegian (Bokm虱)_Norway.850Norwegian (Bokm虱)_Norway.1252Norwegian (Bokm虱)_Norway.1252
norwegian-nynorskNorwegian (Bokm虱)_Norway.850Norwegian (Bokm虱)_Norway.850Norwegian (Bokm虱)_Norway.1252Norwegian-Nynorsk_Norway.1252
polishPolish_Poland.852Polish_Poland.852Polish_Poland.1250Polish_Poland.1250
portuguesePortuguese_Brazil.850Portuguese_Brazil.850Portuguese_Brazil.1252Portuguese_Brazil.1252
portuguese-brazilianPortuguese_Brazil.850Portuguese_Brazil.850Portuguese_Brazil.1252Portuguese_Brazil.1252
russianRussian_Russia.866Russian_Russia.866Russian_Russia.1251Russian_Russia.1251
slovakSlovak_Slovakia.852Slovak_Slovakia.852Slovak_Slovakia.1250Slovak_Slovakia.1250
spanishSpanish_Spain.850Spanish_Spain.850Spanish_Spain.1252Spanish_Spain.1252
spanish-mexicanSpanish_Spain.850Spanish_Spain.850Spanish_Spain.1252Spanish_Mexico.1252
spanish-modernSpanish_Spain.850Spanish_Spain.850Spanish_Spain.1252Spanish_Spain.1252
swedishSwedish_Sweden.850Swedish_Sweden.850Swedish_Sweden.1252Swedish_Sweden.1252
turkishTurkish_Turkey.857Turkish_Turkey.857Turkish_Turkey.1254Turkish_Turkey.1254
chsNULLNULLChinese_People's Republic of China.936Chinese_People's Republic of China.936
chtChinese_Taiwan.950Chinese_Taiwan.950Chinese_Taiwan.950Chinese_Taiwan.950
csyCzech_Czech Republic.852Czech_Czech Republic.852Czech_Czech Republic.1250Czech_Czech Republic.1250
danDanish_Denmark.850Danish_Denmark.850Danish_Denmark.1252Danish_Denmark.1252
nldDutch_Netherlands.850Dutch_Netherlands.850Dutch_Netherlands.1252Dutch_Netherlands.1252
nlbNULLNULLDutch_Belgium.1252Dutch_Belgium.1252
enaNULLNULLEnglish_Australia.1252English_Australia.1252
encNULLNULLEnglish_Canada.1252English_Canada.1252
enzNULLNULLEnglish_New Zealand.1252English_New Zealand.1252
engNULLNULLEnglish_United Kingdom.1252English_United Kingdom.1252
enuEnglish_United States.437English_United States.437English_United States.1252English_United States.1252
usaNULLNULLEnglish_United States.1252English_United States.1252
finFinnish_Finland.850Finnish_Finland.850Finnish_Finland.1252Finnish_Finland.1252
fraFrench_France.850French_France.850French_France.1252French_France.1252
frbNULLNULLFrench_Belgium.1252French_Belgium.1252
frcNULLNULLFrench_Canada.1252French_Canada.1252
frsNULLNULLFrench_Switzerland.1252French_Switzerland.1252
deuGerman_Germany.850German_Germany.850German_Germany.1252German_Germany.1252
deaNULLNULLGerman_Austria.1252German_Austria.1252
desNULLNULLGerman_Switzerland.1252German_Switzerland.1252
ellGreek_Greece.737Greek_Greece.737Greek_Greece.1253Greek_Greece.1253
hunHungarian_Hungary.852Hungarian_Hungary.852Hungarian_Hungary.1250Hungarian_Hungary.1250
islIcelandic_Iceland.850Icelandic_Iceland.850Icelandic_Iceland.1252Icelandic_Iceland.1252
itaItalian_Italy.850Italian_Italy.850Italian_Italy.1252Italian_Italy.1252
itsNULLNULLItalian_Switzerland.1252Italian_Switzerland.1252
korKorean_Korea.949Korean_Korea.949Korean_Korea.949Korean_Korea.949
norNorwegian (Bokm虱)_Norway.850Norwegian (Bokm虱)_Norway.850Norwegian (Bokm虱)_Norway.1252Norwegian (Bokm虱)_Norway.1252
nonNULLNULLNorwegian-Nynorsk_Norway.1252Norwegian-Nynorsk_Norway.1252
plkPolish_Poland.852Polish_Poland.852Polish_Poland.1250Polish_Poland.1250
ptgNULLNULLPortuguese_Portugal.1252Portuguese_Portugal.1252
ptbPortuguese_Brazil.850Portuguese_Brazil.850Portuguese_Brazil.1252Portuguese_Brazil.1252
rusRussian_Russia.866Russian_Russia.866Russian_Russia.1251Russian_Russia.1251
skySlovak_Slovakia.852Slovak_Slovakia.852Slovak_Slovakia.1250Slovak_Slovakia.1250
espSpanish_Spain.850Spanish_Spain.850Spanish_Spain.1252Spanish_Spain.1252
esmNULLNULLSpanish_Mexico.1252Spanish_Mexico.1252
esnNULLNULLSpanish_Spain.1252Spanish_Spain.1252
sveSwedish_Sweden.850Swedish_Sweden.850Swedish_Sweden.1252Swedish_Sweden.1252
trkTurkish_Turkey.857Turkish_Turkey.857Turkish_Turkey.1254Turkish_Turkey.1254

こうしてみると、処理系ごとや、また同じ処理系でもバージョンによって対応状況が少しずつ違うことがわかります。

C++ の場合 このエントリーを含むブックマーク

ロケール文字列bcb6(C++Builder6J)bcb10(C++Builder2006J)vc71(VisualStudio.NET2003)vc8(VisualStudio2005)
ja_JPSucceededFailed: bad locale nameFailed: bad locale nameFailed: bad locale name
ja_JP.SJISSucceededAccessViolationFailed: bad locale nameFailed: bad locale name
ja_JP.sjisSucceeded--Failed: bad locale nameFailed: bad locale name
ja_JP.EUCSucceeded--Failed: bad locale nameFailed: bad locale name
ja_JP.eucJPSucceeded--Failed: bad locale nameFailed: bad locale name
ja_JP.utf8Succeeded--Failed: bad locale nameFailed: bad locale name
japaneseSucceeded--SucceededSucceeded
japanese_JAPANSucceeded--SucceededSucceeded
japanese_JAPAN.932Succeeded--SucceededSucceeded
Japanese_Japan.932Succeeded--SucceededSucceeded
Japanese_Japan.20932Succeeded--SucceededSucceeded
JAPANESE_JAPAN.JA16SJISSucceeded--Failed: bad locale nameFailed: bad locale name
japanese_Japan.ja16sjisSucceeded--Failed: bad locale nameFailed: bad locale name
japanese_Japan.ja16eucSucceeded--Failed: bad locale nameFailed: bad locale name
Japanese_Japan.UTF8Succeeded--Failed: bad locale nameFailed: bad locale name
ja_JP.eucJPSucceeded--Failed: bad locale nameFailed: bad locale name
ja_JP.ujisSucceeded--Failed: bad locale nameFailed: bad locale name
ja_JP.EUCSucceeded--Failed: bad locale nameFailed: bad locale name
japanese.eucSucceeded--Failed: bad locale nameFailed: bad locale name
Japanese-EUCSucceeded--SucceededFailed: bad locale name
jaSucceeded--SucceededFailed: bad locale name
jpnSucceeded--SucceededSucceeded
japanSucceeded--SucceededFailed: bad locale name
C-SJISSucceeded--SucceededFailed: bad locale name
de_DESucceeded--Failed: bad locale nameFailed: bad locale name
de_DE@euroSucceeded--Failed: bad locale nameFailed: bad locale name
de_DESucceeded--Failed: bad locale nameFailed: bad locale name
deSucceeded--Failed: bad locale nameFailed: bad locale name
geSucceeded--SucceededFailed: bad locale name
en_ENSucceeded--Failed: bad locale nameFailed: bad locale name
English_USA.1252Succeeded--SucceededSucceeded
French_France.1252Succeeded--SucceededSucceeded
French_Canada.ACPSucceeded--SucceededSucceeded
French_Canada.OCPSucceeded--SucceededSucceeded
de_DE.iso88591Succeeded--Failed: bad locale nameFailed: bad locale name
de_DE.ISO-8859-1Succeeded--Failed: bad locale nameFailed: bad locale name
chineseSucceeded--SucceededSucceeded
chinese-simplifiedSucceeded--SucceededSucceeded
chinese-traditionalSucceeded--SucceededSucceeded
czechSucceeded--SucceededSucceeded
danishSucceeded--SucceededSucceeded
dutchSucceeded--SucceededSucceeded
dutch-belgianSucceeded--SucceededSucceeded
belgianSucceeded--SucceededSucceeded
englishSucceeded--SucceededSucceeded
english-ausSucceeded--SucceededSucceeded
australianSucceeded--SucceededSucceeded
canadianSucceeded--SucceededSucceeded
english-canSucceeded--SucceededSucceeded
english-nzSucceeded--SucceededSucceeded
english-ukSucceeded--SucceededSucceeded
ukSucceeded--SucceededSucceeded
americanSucceeded--SucceededSucceeded
american englishSucceeded--SucceededSucceeded
american-englishSucceeded--SucceededSucceeded
english-americanSucceeded--SucceededSucceeded
english-usSucceeded--SucceededSucceeded
english-usaSucceeded--SucceededSucceeded
usSucceeded--SucceededSucceeded
finnishSucceeded--SucceededSucceeded
frenchSucceeded--SucceededSucceeded
french-belgianSucceeded--SucceededSucceeded
french-canadianSucceeded--SucceededSucceeded
french-swissSucceeded--SucceededSucceeded
germanSucceeded--SucceededSucceeded
german-austrianSucceeded--SucceededSucceeded
swissSucceeded--SucceededSucceeded
german-swissSucceeded--SucceededSucceeded
greekSucceeded--SucceededSucceeded
hungarianSucceeded--SucceededSucceeded
icelandicSucceeded--SucceededSucceeded
italianSucceeded--SucceededSucceeded
italian-swissSucceeded--SucceededSucceeded
japaneseSucceeded--SucceededSucceeded
koreanSucceeded--SucceededSucceeded
norwegianSucceeded--SucceededSucceeded
norwegian-bokmalSucceeded--SucceededSucceeded
norwegian-nynorskSucceeded--SucceededSucceeded
polishSucceeded--SucceededSucceeded
portugueseSucceeded--SucceededSucceeded
portuguese-brazilianSucceeded--SucceededSucceeded
russianSucceeded--SucceededSucceeded
slovakSucceeded--SucceededSucceeded
spanishSucceeded--SucceededSucceeded
spanish-mexicanSucceeded--SucceededSucceeded
spanish-modernSucceeded--SucceededSucceeded
swedishSucceeded--SucceededSucceeded
turkishSucceeded--SucceededSucceeded
chsSucceeded--SucceededSucceeded
chtSucceeded--SucceededSucceeded
csySucceeded--SucceededSucceeded
danSucceeded--SucceededSucceeded
nldSucceeded--SucceededSucceeded
nlbSucceeded--SucceededSucceeded
enaSucceeded--SucceededSucceeded
encSucceeded--SucceededSucceeded
enzSucceeded--SucceededSucceeded
engSucceeded--SucceededSucceeded
enuSucceeded--SucceededSucceeded
usaSucceeded--SucceededSucceeded
finSucceeded--SucceededSucceeded
fraSucceeded--SucceededSucceeded
frbSucceeded--SucceededSucceeded
frcSucceeded--SucceededSucceeded
frsSucceeded--SucceededSucceeded
deuSucceeded--SucceededSucceeded
deaSucceeded--SucceededSucceeded
desSucceeded--SucceededSucceeded
ellSucceeded--SucceededSucceeded
hunSucceeded--SucceededSucceeded
islSucceeded--SucceededSucceeded
itaSucceeded--SucceededSucceeded
itsSucceeded--SucceededSucceeded
korSucceeded--SucceededSucceeded
norSucceeded--SucceededSucceeded
nonSucceeded--SucceededSucceeded
plkSucceeded--SucceededSucceeded
ptgSucceeded--SucceededSucceeded
ptbSucceeded--SucceededSucceeded
rusSucceeded--SucceededSucceeded
skySucceeded--SucceededSucceeded
espSucceeded--SucceededSucceeded
esmSucceeded--SucceededSucceeded
esnSucceeded--SucceededSucceeded
sveSucceeded--SucceededSucceeded
trkSucceeded--SucceededSucceeded

C++Builder2006 の Access Violation というのは、locale オブジェクトの生成に失敗して例外を返した後、別のロケール名で再度生成しようとすると今度はAccess Violation を起こして落ちてしまった、というものです。これってなんかバグっぽいですね…。

結論 このエントリーを含むブックマーク

日本語(SJIS)を特定したい場合はロケール文字列として "Japanese_Japan.932" を使うのが良さそうです。端折りたい場合は "japanese" あたりが良いかと。

ただ上で試した環境は全部 Windows なので、FreeBSD LinuxOSX でどうなるかは未確認です。

それよりも、システムデフォルトに任せるなら "" で放っておくのが一番ですかそうですか…。

 | 
2004 | 01 | 02 | 03 | 04 | 05 | 06 | 08 | 09 | 10 | 11 | 12 |
2005 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2006 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 11 |