C 文字列操作 新しいページはコチラ
提供: yonewiki
(→文字列の型変換) |
(→文字列と日付・日時・時間の変換) |
||
1行: | 1行: | ||
+ | [[C PlusPlus#Cにもあった技術|C++]]へ戻る | ||
+ | |||
+ | |||
※このページではC言語にも存在していたという意味で記事タイトルがC 文字列操作になっていますが、<br /> | ※このページではC言語にも存在していたという意味で記事タイトルがC 文字列操作になっていますが、<br /> | ||
[[C PlusPlus|C++]]でも同様です。[[C PlusPlus|C++]]だけの機能がある場合は明記します。<br /> | [[C PlusPlus|C++]]でも同様です。[[C PlusPlus|C++]]だけの機能がある場合は明記します。<br /> | ||
<br /> | <br /> | ||
== '''文字列操作''' == | == '''文字列操作''' == | ||
+ | |||
文字列のコピー、連結、比較、一致、区切り文字分割、探索、文字列長取得といった操作を文字列操作と呼びます。上記のような操作はCRT関数として提供されているため、関数の使い方さえ覚えれば簡単に操作できます。 | 文字列のコピー、連結、比較、一致、区切り文字分割、探索、文字列長取得といった操作を文字列操作と呼びます。上記のような操作はCRT関数として提供されているため、関数の使い方さえ覚えれば簡単に操作できます。 | ||
− | + | 更に、文字列の型変換、文字コード変換、大文字小文字変換、半角文字、全角文字変換、ファイルパス操作、ファイル名操作、拡張子取得といった文字列操作の応用もプログラミングでは必要になってきますし、文字列の検索と置換、ファイルへの入出力といった操作までを習得すると概ねの操作ができるようになります。ちなみに、XMLとか、HTMLとか特定の形式のテキストを取り扱う技術についてはここでは、取り上げません。記述するとしたら別の項目になるかと思います。<br /> | |
19行: | 23行: | ||
http://msdn.microsoft.com/ja-jp/library/f0151s4x.aspx<br /> | http://msdn.microsoft.com/ja-jp/library/f0151s4x.aspx<br /> | ||
上記があれば、自分が説明する必要はもうないかなと思うわけですが、一応、自分なりに。<br /> | 上記があれば、自分が説明する必要はもうないかなと思うわけですが、一応、自分なりに。<br /> | ||
+ | |||
+ | ちなみにマルチバイト文字関連の操作は関数が用意されていますが、Windowsストアアプリを作成することはできません。詳細は以下のページの説明のとおりです。変換以外の操作はUnicodeで文字列を扱ってください。つまり、以下で紹介する_mbs***系の操作関数は使えないと考えてください。_wcs***系や_tcs***系でワイド文字を扱う関数にする必要があります。 | ||
+ | http://msdn.microsoft.com/library/windows/apps/jj606124.aspx | ||
=='''文字列長取得'''== | =='''文字列長取得'''== | ||
53行: | 60行: | ||
− | < | + | <syntaxhighlight2 lang="cpp" line start="1"> |
#include <tchar.h> | #include <tchar.h> | ||
int main() { | int main() { | ||
62行: | 69行: | ||
} | } | ||
} | } | ||
− | </ | + | </syntaxhighlight2> |
出力結果 | 出力結果 | ||
− | < | + | <syntaxhighlight2 lang="cpp"> |
0/ 3:cStr0[ 0]=表示:よねウィキの機能<yonewiki> | 0/ 3:cStr0[ 0]=表示:よねウィキの機能<yonewiki> | ||
StrCount=21 | StrCount=21 | ||
73行: | 80行: | ||
2/ 3:cStr0[ 2]=表示:よねウィキの機能2<yonewiki> | 2/ 3:cStr0[ 2]=表示:よねウィキの機能2<yonewiki> | ||
StrCount=22 | StrCount=22 | ||
− | </ | + | </syntaxhighlight2> |
_mb系の関数を利用するには、<nowiki>#include <mbstring.h></nowiki>をインクルードする必要があります。<br /> | _mb系の関数を利用するには、<nowiki>#include <mbstring.h></nowiki>をインクルードする必要があります。<br /> | ||
82行: | 89行: | ||
− | < | + | <syntaxhighlight2 lang="cpp" line start="1"> |
#include <tchar.h> | #include <tchar.h> | ||
#include <mbstring.h> | #include <mbstring.h> | ||
105行: | 112行: | ||
delete[] ppcStr1; | delete[] ppcStr1; | ||
} | } | ||
− | </ | + | </syntaxhighlight2> |
という具合にして、const char→char→_mabslenで文字列長探索が出来ます。出力結果は以下のとおりです。<br /> | という具合にして、const char→char→_mabslenで文字列長探索が出来ます。出力結果は以下のとおりです。<br /> | ||
− | < | + | <syntaxhighlight2 lang="cpp"> |
const マルチバイト文字→マルチバイト文字コピー→_mbslen関数2バイト文字認識文字列長探索 | const マルチバイト文字→マルチバイト文字コピー→_mbslen関数2バイト文字認識文字列長探索 | ||
0/ 4:cStr1[ 0]= | 0/ 4:cStr1[ 0]= | ||
121行: | 128行: | ||
StrCount=22 | StrCount=22 | ||
− | </ | + | </syntaxhighlight2> |
_mbstrlen関数を使う場合はコピー操作が必要にならず、const宣言している文字列変数を使っての文字列長探索ができます。<br /> | _mbstrlen関数を使う場合はコピー操作が必要にならず、const宣言している文字列変数を使っての文字列長探索ができます。<br /> | ||
− | < | + | <syntaxhighlight2 lang="cpp" line start="1"> |
#include <tchar.h> | #include <tchar.h> | ||
#include <mbstring.h> | #include <mbstring.h> | ||
134行: | 141行: | ||
} | } | ||
} | } | ||
− | </ | + | </syntaxhighlight2> |
出力結果は以下のとおりです。<br /> | 出力結果は以下のとおりです。<br /> | ||
− | < | + | <syntaxhighlight2 lang="cpp"> |
const マルチバイト文字→_mbstrlen関数2バイト文字認識文字列長探索 | const マルチバイト文字→_mbstrlen関数2バイト文字認識文字列長探索 | ||
0/ 4:cStr1[ 0]= | 0/ 4:cStr1[ 0]= | ||
150行: | 157行: | ||
StrCount=22 | StrCount=22 | ||
− | </ | + | </syntaxhighlight2> |
といった具合にいろいろな関数があるので、一つづつ掘り下げて理解しておくのも、必要です。こういう違いがあるということを把握していれば、臨機応変に対応しやすくなるかもです。自分は分かったつもりにならずに、常に謙虚に確かめてみる姿勢ってのは、必要なんじゃないかと思います。そして常に、自分が実施するであろうパターンを網羅して確かめる。だから、あえて文字列の配列の場合にどうやればいいのかを探ります。 | といった具合にいろいろな関数があるので、一つづつ掘り下げて理解しておくのも、必要です。こういう違いがあるということを把握していれば、臨機応変に対応しやすくなるかもです。自分は分かったつもりにならずに、常に謙虚に確かめてみる姿勢ってのは、必要なんじゃないかと思います。そして常に、自分が実施するであろうパターンを網羅して確かめる。だから、あえて文字列の配列の場合にどうやればいいのかを探ります。 | ||
180行: | 187行: | ||
で、結局は_tcsncpy_sを使いなさいってことになります。Unicode設定ならワイド文字版で、文字列長に厳しい設定が必要なwcsncpy_sだね。第二引数は配列の大きさ+終端\0のための要素1つ分。バイト数ではないです。動的に生成した変数の場合は配列の大きさが取得できないので、wcslen(_tcslen)のような文字列長取得関数を使って、戻ってきた値に\0の要素のために1を加算した値が良いです。<br /> | で、結局は_tcsncpy_sを使いなさいってことになります。Unicode設定ならワイド文字版で、文字列長に厳しい設定が必要なwcsncpy_sだね。第二引数は配列の大きさ+終端\0のための要素1つ分。バイト数ではないです。動的に生成した変数の場合は配列の大きさが取得できないので、wcslen(_tcslen)のような文字列長取得関数を使って、戻ってきた値に\0の要素のために1を加算した値が良いです。<br /> | ||
− | < | + | <syntaxhighlight2 lang="cpp" line start="1"> |
#include <iostream> | #include <iostream> | ||
//#include<locale.h> tchar.hがインクルードされていれば、いらない。 | //#include<locale.h> tchar.hがインクルードされていれば、いらない。 | ||
242行: | 249行: | ||
return 0; | return 0; | ||
} | } | ||
− | </ | + | </syntaxhighlight2> |
という感じでしたね。無理やり_mbscpy関数を使ってみるとこんな感じですね。unsigned char型は宣言と同時にnew演算子の定義は出来ないようです。const型のcharからはキャストできないから、結局は一度、strcpy_sを使って、char型の文字列に置き換えないといけないです。マルチバイト型の2バイト文字認識操作関数って結局は、char型と同じなので、文字数を数えるときはstrlenで数えないといけない。char型と_mbsxxx関数を行ったり来たりするだけです。<br /> | という感じでしたね。無理やり_mbscpy関数を使ってみるとこんな感じですね。unsigned char型は宣言と同時にnew演算子の定義は出来ないようです。const型のcharからはキャストできないから、結局は一度、strcpy_sを使って、char型の文字列に置き換えないといけないです。マルチバイト型の2バイト文字認識操作関数って結局は、char型と同じなので、文字数を数えるときはstrlenで数えないといけない。char型と_mbsxxx関数を行ったり来たりするだけです。<br /> | ||
出力結果は以下のとおり<br /> | 出力結果は以下のとおり<br /> | ||
− | < | + | <syntaxhighlight2 lang="cpp"> |
_tcslen(cStr0[i])=21 | _tcslen(cStr0[i])=21 | ||
ppcStr0=表示:よねウィキの機能<yonewiki>, | ppcStr0=表示:よねウィキの機能<yonewiki>, | ||
289行: | 296行: | ||
ppucStr2=表示:よねウィキの機能2<yonewiki>, | ppucStr2=表示:よねウィキの機能2<yonewiki>, | ||
cStr1=表示:よねウィキの機能2<yonewiki>, | cStr1=表示:よねウィキの機能2<yonewiki>, | ||
− | </ | + | </syntaxhighlight2> |
上記に加えて、コピーする文字数を引数とするcpyの前にnが付く関数_tcsncpy_s/wcsncpy_s/strncpy_s/_mbsncpy_sにする場合は<br /> | 上記に加えて、コピーする文字数を引数とするcpyの前にnが付く関数_tcsncpy_s/wcsncpy_s/strncpy_s/_mbsncpy_sにする場合は<br /> | ||
− | < | + | <syntaxhighlight2 lang="cpp"> |
… | … | ||
… | … | ||
307行: | 314行: | ||
… | … | ||
… | … | ||
− | </ | + | </syntaxhighlight2> |
と、4つの引数をとるように記述します。第4引数が出力する最大文字の配列数です。出力する文字数と考えることもできます。マルチバイト文字の場合には出力する文字数を指定できるのは効果的で、先頭から何バイト目で区切れば日本語文字が分断されないかの判断もしてくれながらの出力となります。この出力する文字数をあえてバイト単位で指定する_mbsnbcpy_sもあります。ただし、コピー先の文字列の配列はstrlenのようなバイト数分で準備する必要があることに注意が必要です。出力文字数を指定する場合は文字列全体の長さではなく、指定した文字数で必要な文字列バイト数を算出しておいて、メモリを確保するように処理を記述するのが良いかもしれません。ここでは強制キャストを使いましたが、もともとの文字列がunsigned charとして定義されているものをコピーするときに_mbs系の文字列コピーを利用するというのが自然な使い方になります。<br /> | と、4つの引数をとるように記述します。第4引数が出力する最大文字の配列数です。出力する文字数と考えることもできます。マルチバイト文字の場合には出力する文字数を指定できるのは効果的で、先頭から何バイト目で区切れば日本語文字が分断されないかの判断もしてくれながらの出力となります。この出力する文字数をあえてバイト単位で指定する_mbsnbcpy_sもあります。ただし、コピー先の文字列の配列はstrlenのようなバイト数分で準備する必要があることに注意が必要です。出力文字数を指定する場合は文字列全体の長さではなく、指定した文字数で必要な文字列バイト数を算出しておいて、メモリを確保するように処理を記述するのが良いかもしれません。ここでは強制キャストを使いましたが、もともとの文字列がunsigned charとして定義されているものをコピーするときに_mbs系の文字列コピーを利用するというのが自然な使い方になります。<br /> | ||
329行: | 336行: | ||
例によって_sのついた連結先文字列の配列サイズを明記する関数に_lのついた個別ロケール設定関数。そして連結させたい文字列の文字数を記述するncatに文字数をバイト数で指定するnbcat。あとはワイド文字のwcsで始まる関数。マルチバイトのstrで始まる関数。マルチバイト2バイト文字対応の_mbsで始まる関数。全部で22種類。引数は文字列コピーと同じですが、コピー先の変数が既に文字列が格納されてる\0で終わる文字列になっていて、処理をした結果、第一引数の文字列先頭アドレスの中身が文字列連結した結果になるという点が異なると覚えれば、連結とコピーは似ていると覚えればよいかと思います。先の文字列コピーのプログラムのコピーcpy系関数の後ろに連結cat系関数を追加して、文字列を2回繰り返されるようにしたサンプルです。所謂(いわゆる)、手抜きです。ただし、連結関数では連結後の文字列の配列大きさを要求されるため、あらかじめ動的に確保する領域が2倍になっていることに注意して下さい。<br /> | 例によって_sのついた連結先文字列の配列サイズを明記する関数に_lのついた個別ロケール設定関数。そして連結させたい文字列の文字数を記述するncatに文字数をバイト数で指定するnbcat。あとはワイド文字のwcsで始まる関数。マルチバイトのstrで始まる関数。マルチバイト2バイト文字対応の_mbsで始まる関数。全部で22種類。引数は文字列コピーと同じですが、コピー先の変数が既に文字列が格納されてる\0で終わる文字列になっていて、処理をした結果、第一引数の文字列先頭アドレスの中身が文字列連結した結果になるという点が異なると覚えれば、連結とコピーは似ていると覚えればよいかと思います。先の文字列コピーのプログラムのコピーcpy系関数の後ろに連結cat系関数を追加して、文字列を2回繰り返されるようにしたサンプルです。所謂(いわゆる)、手抜きです。ただし、連結関数では連結後の文字列の配列大きさを要求されるため、あらかじめ動的に確保する領域が2倍になっていることに注意して下さい。<br /> | ||
− | < | + | <syntaxhighlight2 lang="cpp" line start="1"> |
#include <iostream> | #include <iostream> | ||
//#include<locale.h> tchar.hがインクルードされていればいらない。 | //#include<locale.h> tchar.hがインクルードされていればいらない。 | ||
394行: | 401行: | ||
return 0; | return 0; | ||
} | } | ||
− | </ | + | </syntaxhighlight2> |
出力結果<br /> | 出力結果<br /> | ||
− | < | + | <syntaxhighlight2 lang="cpp"> |
_tcslen(cStr0[i])=21 | _tcslen(cStr0[i])=21 | ||
ppcStr0=表示:よねウィキの機能<yonewiki>表示:よねウィキの機能<yonewiki>, | ppcStr0=表示:よねウィキの機能<yonewiki>表示:よねウィキの機能<yonewiki>, | ||
441行: | 448行: | ||
ppucStr2=表示:よねウィキの機能2<yonewiki>表示:よねウィキの機能2<yonewiki>表示:よねウィキの機能2<yonewiki>表示:よねウィキの機能2<yonewiki>, | ppucStr2=表示:よねウィキの機能2<yonewiki>表示:よねウィキの機能2<yonewiki>表示:よねウィキの機能2<yonewiki>表示:よねウィキの機能2<yonewiki>, | ||
cStr1=表示:よねウィキの機能2<yonewiki>, | cStr1=表示:よねウィキの機能2<yonewiki>, | ||
− | </ | + | </syntaxhighlight2> |
=='''文字列比較'''== | =='''文字列比較'''== | ||
474行: | 481行: | ||
− | < | + | <syntaxhighlight2 lang="cpp" line start="1"> |
#include <iostream> | #include <iostream> | ||
//#include<locale.h> wchar.hがインクルードされていれば、いらない。 | //#include<locale.h> wchar.hがインクルードされていれば、いらない。 | ||
562行: | 569行: | ||
return 0; | return 0; | ||
} | } | ||
− | </ | + | </syntaxhighlight2> |
出力結果 | 出力結果 | ||
− | < | + | <syntaxhighlight2 lang="cpp"> |
_tcslen(cStr0[i])=22 | _tcslen(cStr0[i])=22 | ||
ppcStr0=表示:よねウィキの機能0<yonewiki>表示:よねウィキの機能0<yonewiki>, | ppcStr0=表示:よねウィキの機能0<yonewiki>表示:よねウィキの機能0<yonewiki>, | ||
660行: | 667行: | ||
i=3, k=3, iCmpResult=0, | i=3, k=3, iCmpResult=0, | ||
− | </ | + | </syntaxhighlight2> |
と、こんな感じです。結果を見るとわかるのですが、1,-1,0で結果が表現され、先頭から比較して、一番最初に異なる文字同志を比較したときの結果、文字コードの値が大きかったか小さかったかで、1と-1とに結果が分かれます。これを使って昇順に並べたりすることも出来ます。もちろん0が返ってきたときは、完全一致です。等しかったということになります。<br /> | と、こんな感じです。結果を見るとわかるのですが、1,-1,0で結果が表現され、先頭から比較して、一番最初に異なる文字同志を比較したときの結果、文字コードの値が大きかったか小さかったかで、1と-1とに結果が分かれます。これを使って昇順に並べたりすることも出来ます。もちろん0が返ってきたときは、完全一致です。等しかったということになります。<br /> | ||
696行: | 703行: | ||
<br /> | <br /> | ||
という具合の動作であります。collの特徴的なのは辞書順と呼んでいる比較の概念だと思います。ASCIIコードでは大文字と小文字とでは、小文字の方が大きい文字コード番号が付与されていますが、wcs**coll系の比較をする関数では、小文字の方が値が小さいものとして判定してくれます。漢字の範囲になるとロケールで指定したcp932の文字コード順で比較してくれます。阿という文字と哀という文字はUnicode(UTF16)では阿-0x963F 哀-0x54C0 表-0x8868であり、Shift_JISのcp932では阿-0x88A2 哀-0x88A3 表-0x955Cと定義されていますから、阿<nowiki><</nowiki>哀<nowiki><</nowiki>表 のように比較をしてくれます。coll系の関数を使わない場合は 哀<nowiki><</nowiki>表<nowiki><</nowiki>阿のように比較されます。この阿や哀や表という名前のファイル名のテキストをWindowsのエクスプローラで昇順表示すると、この順番になることも確認できます。Shift_JISコード順でソートされてるんだなぁと確認が出来ると思います。Cp932の半角記号あたりの辞書順ってのは、どうなってるんでしょうね。これもまた今度しらべてみたいと思います。ファイル名に使えない文字あたりはどんな順番なんだろうか? | という具合の動作であります。collの特徴的なのは辞書順と呼んでいる比較の概念だと思います。ASCIIコードでは大文字と小文字とでは、小文字の方が大きい文字コード番号が付与されていますが、wcs**coll系の比較をする関数では、小文字の方が値が小さいものとして判定してくれます。漢字の範囲になるとロケールで指定したcp932の文字コード順で比較してくれます。阿という文字と哀という文字はUnicode(UTF16)では阿-0x963F 哀-0x54C0 表-0x8868であり、Shift_JISのcp932では阿-0x88A2 哀-0x88A3 表-0x955Cと定義されていますから、阿<nowiki><</nowiki>哀<nowiki><</nowiki>表 のように比較をしてくれます。coll系の関数を使わない場合は 哀<nowiki><</nowiki>表<nowiki><</nowiki>阿のように比較されます。この阿や哀や表という名前のファイル名のテキストをWindowsのエクスプローラで昇順表示すると、この順番になることも確認できます。Shift_JISコード順でソートされてるんだなぁと確認が出来ると思います。Cp932の半角記号あたりの辞書順ってのは、どうなってるんでしょうね。これもまた今度しらべてみたいと思います。ファイル名に使えない文字あたりはどんな順番なんだろうか? | ||
+ | |||
+ | |||
+ | coll系の比較の中身を見るための関数としては、strxfrm関数がある。これがロケール設定にしたがった照合順序文字列を生成してくれる。これは文字列ではあるが、書き出すことは出来ない照合のための文字コードだと考えればよい。中身をみたければstrxfrmで変換してバイトコードを確認することができるが、ロケール設定によってはなぜこんな変換になるんだ?というような不思議な変換がなされる。とくにen-US.utf8とかになると発音記号のアクセントや、特殊記号を別の辞書順と管理するため、1つの文字列が3つに分割され、1文字でもトークンとなるバイトコードが2つと文字列、アクセント、大文字小文字で3つのバイトコードで5バイトになる。更に特殊記号がひとつでも現れる文字列なら4つに分割され、特殊記号の使われる位置情報まで生成される。このような照合順序規則がロケールごとに存在する。coll系の比較関数はとんでもなく複雑な処理を行う比較関数なのだ。それゆえ通常のcmp系の関数と比べても、処理時間がかかる。localeごとの照合順序について理解しているならば、strxfrmで返還後のコードを使って、strcoll関数のような比較処理を高速化することも可能となる。ロケールによる処理も含めた関数の利用が必要になるケースもあるかもしれないが、ロケールの特徴を理解して、使うのも大事だし、使いどころが肝心となる。 | ||
'''★豆知識''' | '''★豆知識''' | ||
'''Unicodeの符号化方式UTF-16とは…''' | '''Unicodeの符号化方式UTF-16とは…''' | ||
日本語の範囲ではUTF16は2バイト文字と考えて良いですが、Unicode全体では0x10FFFFまで利用することになっていますので、0x10000以上の値を持つ文字コードは4バイト文字になります。この0x10000以上の値になる場合は、ビット列で表現すると110110????xxxxxx 110111xxxxxxxxxxのような形式になり????の部分のには上位ビットと下位ビットを16ビットずつに分けた時に0xUUUUDDDDと表記するならば、0xUUUUは0x0001~0x0010の値となり得て、そのUUUU-1の値が????に入ります。xの部分には下位DDDDのビット列そのものが | 日本語の範囲ではUTF16は2バイト文字と考えて良いですが、Unicode全体では0x10FFFFまで利用することになっていますので、0x10000以上の値を持つ文字コードは4バイト文字になります。この0x10000以上の値になる場合は、ビット列で表現すると110110????xxxxxx 110111xxxxxxxxxxのような形式になり????の部分のには上位ビットと下位ビットを16ビットずつに分けた時に0xUUUUDDDDと表記するならば、0xUUUUは0x0001~0x0010の値となり得て、そのUUUU-1の値が????に入ります。xの部分には下位DDDDのビット列そのものが | ||
− | 入ったような値になります。そういう意味ではUnicodeのUTF-16という符号化方式では16bit(2byte)だったり32bit(4byte) | + | 入ったような値になります。そういう意味ではUnicodeのUTF-16という符号化方式では16bit(2byte)だったり32bit(4byte)のコードになります。※更に異体字セレクタというコードが付与されるケースがあり、付与される場合はUnicode文字番号つづけて、E0100、E0101、E0102…といった値が付与されます。UTF-16の2バイトコードであれば、さらにDB40 DD00という4バイトが付与され一文字が6文字になります。似ている文字をこのセレクタ番号によって切り替えるという仕組みです。したがって2バイト文字は6バイトに、4バイト文字は8バイトになります。テキストエディタおよびフォントも対応していないと使えないような特殊な文字ですが、存在している以上、対応しなければならない可能性はあります。現状はあまり対応されていないようですが、メモ帳でさえも異体字セレクタに対応しているというのが現実です。 |
'''Unicodeの符号化方式UTF-8とは…''' | '''Unicodeの符号化方式UTF-8とは…''' | ||
707行: | 717行: | ||
x0,x1,x2,x3, x4,x5,x6,x7, x8,x9,xA,xB, xC,xD,xE,xFと表現すると、 | x0,x1,x2,x3, x4,x5,x6,x7, x8,x9,xA,xB, xC,xD,xE,xFと表現すると、 | ||
(1110),(x0,x1,x2,x3),(10,x4,x5),(x6,x7, x8,x9),(10,xA,xB),(xC,xD,xE,xF)となります。 | (1110),(x0,x1,x2,x3),(10,x4,x5),(x6,x7, x8,x9),(10,xA,xB),(xC,xD,xE,xF)となります。 | ||
− | 文字の先頭に3バイトなら3つの1が付き、1バイト目を構成し、 | + | 文字の先頭に3バイトなら3つの1が付き、1バイト目を構成し、 次のバイト以降はバイト先頭に全て10をつける。おかげさまで、1バイト目の下位4bitと、3バイト目の下位4bitの16進数だけはそのままだけど、他のbitは16進表記が、変化します。読み起こすのは大変ですね。文字列の最初を見つけたら、そこから文字列に起こしていけば良いですが、新しい変換表を考えないと直感的にはUnicode文字のコード表には表現できないですね。UTF-8の場合、異体字セレクタはF3 A0 84 80という4バイトが不可されて、3バイト文字は7バイト 4バイト文字は8バイトになります。セレクタがひとつ変化する都度最後の2バイトが80→81→82と変化していきます。 |
=='''文字列区切り文字分割'''== | =='''文字列区切り文字分割'''== | ||
730行: | 740行: | ||
比較関数よりは少ないけど、やっぱりマルチバイト版、マルチバイト2バイト文字対応版、ワイド文字版、それに_sをつけた文字列長を指定するセキュア版と個別ロケール指定をする_lのロケール版があります。_l版についてはココまで使い方を触れてこなかったのですが、 | 比較関数よりは少ないけど、やっぱりマルチバイト版、マルチバイト2バイト文字対応版、ワイド文字版、それに_sをつけた文字列長を指定するセキュア版と個別ロケール指定をする_lのロケール版があります。_l版についてはココまで使い方を触れてこなかったのですが、 | ||
− | < | + | <syntaxhighlight2 lang="cpp"> |
_locale_t locale; | _locale_t locale; | ||
locale = _tsetlocale(LC_ALL, _T("Japanese")); | locale = _tsetlocale(LC_ALL, _T("Japanese")); | ||
− | </ | + | </syntaxhighlight2> |
として、localeという変数に_locale_t型の値を_tsetlocaleの返り値として格納しておいたものを関数の最後の引数にします。<br /> | として、localeという変数に_locale_t型の値を_tsetlocaleの返り値として格納しておいたものを関数の最後の引数にします。<br /> | ||
コマンドプロンプトで動作確認してるだけの段階でlocale変数を利用しても、文字化けしか起こせないと思うので、テキスト出力とかを覚えてから試してみるといいかもしれません。<br /> | コマンドプロンプトで動作確認してるだけの段階でlocale変数を利用しても、文字化けしか起こせないと思うので、テキスト出力とかを覚えてから試してみるといいかもしれません。<br /> | ||
758行: | 768行: | ||
区切り文字として複数の文字を指定できますが、それぞれ1文字が独立した区切り文字ですので、// のような2文字以上で構成される区切り文字はこの関数だけでは対応できません。新しい手法が必要になります。 | 区切り文字として複数の文字を指定できますが、それぞれ1文字が独立した区切り文字ですので、// のような2文字以上で構成される区切り文字はこの関数だけでは対応できません。新しい手法が必要になります。 | ||
− | < | + | <syntaxhighlight2 lang="cpp" line start="1"> |
#include <iostream> | #include <iostream> | ||
#include <tchar.h> | #include <tchar.h> | ||
918行: | 928行: | ||
return 0; | return 0; | ||
} | } | ||
− | </ | + | </syntaxhighlight2> |
という具合にtcstok_s関数を使えば、並列してトークン処理が進められるようです。第3引数の参照というC++独自の型を使って、44行目 78行目での最初の呼び出し(エスタブリッシュとも表現します。エスタブリッシュショットというと撮影なんかでワンシーンの手前に一枚絵の風景絵を置くことで、時間帯を表現したりする手法を指します。夜景がシーンの前に入れば室内に映像が切り替わっても夜の出来事であるように示唆するものです。)をして、111、114、131行目のように連続して現れるであろう区切り文字を検索します。111,114行目では、もう区切り文字が現れることがないことがわかっているのですが、2個目のトークンを取得するために実行したり、ループ処理を終わらせるために再度、実行したりという手法で使っています。アイデア次第でなんでもありです。最初にカンマ区切りでトークンを取得するのですが、その間で、さらにカンマ区切りトークンの中に必ず一度現れる、スラッシュによるトークン処理を入れこんでいます。区切り文字が違うだけで全く同じ処理です。こういうプログラム記法は普通はしません。通常は、関数のようなサブプログラムにして、関数を呼び出すことで同じ処理になるように記述します。C++の場合は関数でなくても、クラスのメンバ関数にしても良い訳です。結局同じことですが…。<br /> | という具合にtcstok_s関数を使えば、並列してトークン処理が進められるようです。第3引数の参照というC++独自の型を使って、44行目 78行目での最初の呼び出し(エスタブリッシュとも表現します。エスタブリッシュショットというと撮影なんかでワンシーンの手前に一枚絵の風景絵を置くことで、時間帯を表現したりする手法を指します。夜景がシーンの前に入れば室内に映像が切り替わっても夜の出来事であるように示唆するものです。)をして、111、114、131行目のように連続して現れるであろう区切り文字を検索します。111,114行目では、もう区切り文字が現れることがないことがわかっているのですが、2個目のトークンを取得するために実行したり、ループ処理を終わらせるために再度、実行したりという手法で使っています。アイデア次第でなんでもありです。最初にカンマ区切りでトークンを取得するのですが、その間で、さらにカンマ区切りトークンの中に必ず一度現れる、スラッシュによるトークン処理を入れこんでいます。区切り文字が違うだけで全く同じ処理です。こういうプログラム記法は普通はしません。通常は、関数のようなサブプログラムにして、関数を呼び出すことで同じ処理になるように記述します。C++の場合は関数でなくても、クラスのメンバ関数にしても良い訳です。結局同じことですが…。<br /> | ||
1,120行: | 1,130行: | ||
というわけで、これくらいできて当然という変換をやってみます。 | というわけで、これくらいできて当然という変換をやってみます。 | ||
− | < | + | <syntaxhighlight2 lang="cpp" line start="1"> |
#include <string> | #include <string> | ||
#include <stdlib.h> | #include <stdlib.h> | ||
1,281行: | 1,291行: | ||
} | } | ||
} | } | ||
− | </ | + | </syntaxhighlight2> |
上から<br /> | 上から<br /> | ||
char(LPSTR)→TCHAR(LPTSTR)<br /> | char(LPSTR)→TCHAR(LPTSTR)<br /> | ||
1,318行: | 1,328行: | ||
更に変換を続けたのものが以下になります。 | 更に変換を続けたのものが以下になります。 | ||
− | < | + | <syntaxhighlight2 lang="cpp" line start="1"> |
_tsetlocale(LC_ALL, _T("Japanese")); | _tsetlocale(LC_ALL, _T("Japanese")); | ||
_locale_t locale; | _locale_t locale; | ||
1,590行: | 1,600行: | ||
delete[] sizeReturnValue; | delete[] sizeReturnValue; | ||
delete[] pnStrArrayElement; | delete[] pnStrArrayElement; | ||
− | </ | + | </syntaxhighlight2> |
− | + | _bstr_t型からの変換に関するサンプルを追加しました。 | |
− | + | 型変換とは関係ない部分になりますが、配列のサイズ確保処理について補足しておきますと、文字列配列の大きさは動的に生成した文字列配列からは取得することはできません。動的に生成したときの大きさをプログラマ自身が管理する必要があります。そのことを知ることができるのが上記の64行目のprintf文です。ここで動的に生成した文字列配列の大きさをsizeof関数で表示していますが、配列の大きさは32bitアプリならば、要素数2つなので4byte*2[配列要素数]=8byte(4byte=32bitでひとつのアドレス ※8bit=1byte)になるはずですが、4byteになっています。これはポインタ変数の大きさ、アドレス記憶変数ひとつ分の大きさになっていて、実際の配列サイズが返ってこないことが確認できます。 | |
− | < | + | 話は戻って… |
+ | |||
+ | 上記のように変換を進めていて気づくことですが、それぞれの型は取り扱える文字コード長が異なります。_bstr_tやCComBSTRはマルチバイト文字とワイド文字の両方に対応していて、プロジェクト設定にしたがって記憶する文字型を切り替えています。CStringAはマルチバイト文字、CStringWはワイド文字です。stringとSystem::Stringはマルチバイト文字を扱うようになっています。したがって、変換時にはマルチバイト文字、ワイド文字変換が必要になるケースと必要ないケース。あるいは、プロジェクトの設定によって決まるケースがあるわけです。そのことから、_bstr_tやCComBSTを利用しておくという、ある程度、文字列の世界を熟知している人だけが選ぶ道があるようにも思えるわけです。マイクロソフトの用意したものを使うにしても賢い選択というのが、その時代、時代によって存在することになります。 | ||
+ | |||
+ | 開発するプログラムの枠組みによってはマルチバイトやワイド文字といった切り替えは気にしないという人もいるのかもしれません。具体的にどのように変換処理を記述するかについても、そのときそのときで違ってくることもあるのかもしれませんね。 | ||
+ | |||
+ | 変換の種類がたくさんありますが、wchar_tとcharの変換をおぼえれば、それぞれの特殊な型をchar型に変換する手法とcharからそれぞれの型に変換する手法をマスターすれば、変換手順は長くなる可能性があるものの、とにかくすべてを網羅できるわけです。特殊な型から特殊な型へのダイレクトな変換は覚えなくてもなんとかなる。覚えた方が楽になる。そんな感じです。それぞれの人の考え方にあわせて、覚える量を調節すれば済む話です。 | ||
+ | |||
+ | マイクロソフトの説明書にも簡単な変換に関する文書があります。 | ||
+ | http://msdn.microsoft.com/ja-jp/library/ms235631(v=vs.110).aspx | ||
+ | |||
+ | ここに記述している内容とさほど差はありません。わかりやすい方を参考にしてみて下さい。 | ||
+ | |||
+ | では引き続き、変換のサンプルを… | ||
+ | |||
+ | <syntaxhighlight2 lang="cpp" line start="1"> | ||
//★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
//・CComBSTR→char | //・CComBSTR→char | ||
1,791行: | 1,816行: | ||
//動的確保変数の解放 | //動的確保変数の解放 | ||
delete[] psysstring_StrCnv; | delete[] psysstring_StrCnv; | ||
− | </ | + | </syntaxhighlight2> |
引き続き、変換のサンプルを記述していきます。残るはCComBSTR、CStringA、CStringW、string、System::String基準の変換ですね。 | 引き続き、変換のサンプルを記述していきます。残るはCComBSTR、CStringA、CStringW、string、System::String基準の変換ですね。 | ||
− | < | + | <syntaxhighlight2 lang="cpp" line start="1"> |
//★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
//・CStringA→char | //・CStringA→char | ||
1,986行: | 2,011行: | ||
//動的確保変数の解放 | //動的確保変数の解放 | ||
delete[] psysstring_StrCnv; | delete[] psysstring_StrCnv; | ||
− | </ | + | </syntaxhighlight2> |
+ | |||
+ | <syntaxhighlight2 lang="cpp" line start="1"> | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //・CStringW→char | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | _tprintf(_T("\n文字列の型変換CStringW→char\n")); | ||
+ | |||
+ | const CStringW cstringwOrigin[] = {_T("CStringW型の変数 配列要素1"),_T("CStringW型の変数 配列要素2"),_T("CStringW型の変数 配列要素3")}; | ||
+ | |||
+ | printf("%d\n", sizeof(*cstringwOrigin)); | ||
+ | printf("%d\n", sizeof(cstringwOrigin)); | ||
+ | |||
+ | *pnStrArrayElement = sizeof(cstringwOrigin)/sizeof(*cstringwOrigin); | ||
+ | |||
+ | ppcStrCnv = new char*[*pnStrArrayElement];//要素数分の大きさ+1を確保 | ||
+ | |||
+ | //変換 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | |||
+ | wcstombs_s(sizeReturnValue, NULL, 0,cstringwOrigin[i], 0); | ||
+ | ppcStrCnv[i] = new char[*sizeReturnValue]; | ||
+ | wcstombs_s(sizeReturnValue, ppcStrCnv[i], *sizeReturnValue,cstringwOrigin[i], *sizeReturnValue); | ||
+ | } | ||
+ | |||
+ | //char出力 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | printf("%s\n",*(ppcStrCnv + i)); | ||
+ | } | ||
+ | |||
+ | //動的確保変数の解放 | ||
+ | for(int i = 0;i < *pnStrArrayElement ;i++){ | ||
+ | delete[] *(ppcStrCnv + i); | ||
+ | } | ||
+ | delete[] ppcStrCnv; | ||
+ | |||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //・CStringW→TCHAR | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | _tprintf(_T("\n文字列の型変換CStringW→TCHAR\n")); | ||
+ | |||
+ | pptcStrCnv = new TCHAR*[*pnStrArrayElement];//要素数分の大きさ+1を確保 | ||
+ | |||
+ | //変換 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | |||
+ | #ifdef UNICODE | ||
+ | *sizeReturnValue = _tcslen(cstringwOrigin[i]) + 1; | ||
+ | pptcStrCnv[i] = new TCHAR[*sizeReturnValue]; | ||
+ | _tcscpy_s(pptcStrCnv[i], *sizeReturnValue, cstringwOrigin[i]); | ||
+ | #else | ||
+ | wcstombs_s(sizeReturnValue, NULL, 0,cstringwOrigin[i], 0); | ||
+ | ppcStrCnv[i] = new char[*sizeReturnValue]; | ||
+ | wcstombs_s(sizeReturnValue, ppcStrCnv[i], *sizeReturnValue,cstringwOrigin[i], *sizeReturnValue); | ||
+ | #endif | ||
+ | } | ||
+ | |||
+ | //char出力 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | _tprintf(_T("%s\n"),*(pptcStrCnv + i)); | ||
+ | } | ||
+ | |||
+ | //動的確保変数の解放 | ||
+ | for(int i = 0;i < *pnStrArrayElement ;i++){ | ||
+ | delete[] *(pptcStrCnv + i); | ||
+ | } | ||
+ | delete[] pptcStrCnv; | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //・CStringW→_bstr_t(マルチバイト文字) | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | _tprintf(_T("\n文字列の型変換CStringA→CComBSTR\n")); | ||
+ | |||
+ | pbstrt_StrCnv = new _bstr_t[*pnStrArrayElement];//要素数分の大きさ+1を確保 | ||
+ | |||
+ | //変換 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | pbstrt_StrCnv[i] = cstringwOrigin[i]; | ||
+ | } | ||
+ | |||
+ | //出力 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | //無変換出力 | ||
+ | printf("%s\n",(char*)pbstrt_StrCnv[i]); | ||
+ | _tprintf(_T("%s\n"),(wchar_t*)pbstrt_StrCnv[i]); | ||
+ | } | ||
+ | |||
+ | //動的確保変数の解放 | ||
+ | delete[] pbstrt_StrCnv; | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //・CStringW→CStringA(マルチバイト文字) | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | _tprintf(_T("\n文字列の型変換CStringW→CStringA\n")); | ||
+ | |||
+ | pcstringa_StrCnv = new CStringA[*pnStrArrayElement];//要素数分の大きさ+1を確保 | ||
+ | |||
+ | //変換 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | pcstringa_StrCnv[i] = cstringwOrigin[i]; | ||
+ | } | ||
+ | |||
+ | //出力 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | //char変換出力 | ||
+ | printf("%s\n",pcstringa_StrCnv[i]); | ||
+ | } | ||
+ | |||
+ | //動的確保変数の解放 | ||
+ | delete[] pcstringa_StrCnv; | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //・CStringA→CStringW(ワイド文字) | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | _tprintf(_T("\n文字列の型変換CStringA→CStringW\n")); | ||
+ | |||
+ | pcstringw_StrCnv = new CStringW[*pnStrArrayElement];//要素数分の大きさ+1を確保 | ||
+ | |||
+ | //変換 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | pcstringw_StrCnv[i] = cstringaOrigin[i]; | ||
+ | } | ||
+ | |||
+ | //出力 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | //wchar_t出力 | ||
+ | wprintf(L"%s\n",pcstringw_StrCnv[i]); | ||
+ | } | ||
+ | |||
+ | //動的確保変数の解放 | ||
+ | delete[] pcstringw_StrCnv; | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //・CStringW→string(マルチバイト文字) | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | _tprintf(_T("\n文字列の型変換CStringW→string\n")); | ||
+ | |||
+ | pstring_StrCnv = new string[*pnStrArrayElement];//要素数分の大きさ+1を確保 | ||
+ | |||
+ | //変換 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | wcstombs_s(sizeReturnValue, NULL, 0,cstringwOrigin[i], 0); | ||
+ | char* pcStrTemp = new char[*sizeReturnValue]; | ||
+ | wcstombs_s(sizeReturnValue, pcStrTemp, *sizeReturnValue,cstringwOrigin[i], *sizeReturnValue); | ||
+ | pstring_StrCnv[i] = pcStrTemp; | ||
+ | delete[] pcStrTemp; | ||
+ | } | ||
+ | |||
+ | //出力 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | //char変換出力 | ||
+ | printf("%s\n",pstring_StrCnv[i].c_str()); | ||
+ | } | ||
+ | |||
+ | //動的確保変数の解放 | ||
+ | delete[] pstring_StrCnv; | ||
+ | |||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //・CStringW→SystemString(マルチバイト文字) | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | _tprintf(_T("\n文字列の型変換CStringW→SystemString\n")); | ||
+ | |||
+ | psysstring_StrCnv = gcnew array<String^>(*pnStrArrayElement); | ||
+ | //変換 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | wcstombs_s(sizeReturnValue, NULL, 0,cstringwOrigin[i], 0); | ||
+ | char* pcStrTemp = new char[*sizeReturnValue]; | ||
+ | wcstombs_s(sizeReturnValue, pcStrTemp, *sizeReturnValue,cstringwOrigin[i], *sizeReturnValue); | ||
+ | System::IntPtr ptr(pcStrTemp); | ||
+ | psysstring_StrCnv[i] = Marshal::PtrToStringAnsi(ptr); | ||
+ | } | ||
+ | |||
+ | //出力 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | //char変換出力 | ||
+ | printf("%s\n",psysstring_StrCnv[i]); | ||
+ | //TCHAR変換出力 | ||
+ | #ifdef UNICODE | ||
+ | _tprintf(_T("%s\n"),PtrToStringChars(psysstring_StrCnv[i])); | ||
+ | #else | ||
+ | _tprintf(_T("%s\n"),psysstring_StrCnv[i]); | ||
+ | #endif | ||
+ | } | ||
+ | |||
+ | //動的確保変数の解放 | ||
+ | delete[] psysstring_StrCnv; | ||
+ | </syntaxhighlight2> | ||
+ | <syntaxhighlight2 lang="cpp" line start="1"> | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //・string→char | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | _tprintf(_T("\n文字列の型変換string→char\n")); | ||
+ | |||
+ | const string stringOrigin[] = {"string型の変数 配列要素1","string型の変数 配列要素2","string型の変数 配列要素3"}; | ||
+ | |||
+ | printf("%d\n", sizeof(*stringOrigin)); | ||
+ | printf("%d\n", sizeof(stringOrigin)); | ||
+ | |||
+ | *pnStrArrayElement = sizeof(stringOrigin)/sizeof(*stringOrigin); | ||
+ | |||
+ | ppcStrCnv = new char*[*pnStrArrayElement];//要素数分の大きさ+1を確保 | ||
+ | |||
+ | //変換 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | *sizeReturnValue = strlen(stringOrigin[i].c_str()) + 1; | ||
+ | ppcStrCnv[i] = new char[*sizeReturnValue]; | ||
+ | strcpy_s(ppcStrCnv[i], *sizeReturnValue, stringOrigin[i].c_str()); | ||
+ | } | ||
+ | |||
+ | //char出力 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | printf("%s\n",*(ppcStrCnv + i)); | ||
+ | } | ||
+ | |||
+ | //動的確保変数の解放 | ||
+ | for(int i = 0;i < *pnStrArrayElement ;i++){ | ||
+ | delete[] *(ppcStrCnv + i); | ||
+ | } | ||
+ | delete[] ppcStrCnv; | ||
+ | |||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //・string→TCHAR | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | _tprintf(_T("\n文字列の型変換string→TCHAR\n")); | ||
+ | |||
+ | pptcStrCnv = new TCHAR*[*pnStrArrayElement];//要素数分の大きさ+1を確保 | ||
+ | |||
+ | //変換 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | |||
+ | #ifdef UNICODE | ||
+ | mbstowcs_s(sizeReturnValue, NULL, 0,stringOrigin[i].c_str(), 0); | ||
+ | pptcStrCnv[i] = new TCHAR[*sizeReturnValue]; | ||
+ | mbstowcs_s(sizeReturnValue, pptcStrCnv[i], *sizeReturnValue,stringOrigin[i].c_str(), *sizeReturnValue); | ||
+ | #else | ||
+ | *sizeReturnValue = strlen(stringOrigin[i].c_str()) + 1; | ||
+ | pptcStrCnv[i] = new TCHAR[*sizeReturnValue]; | ||
+ | _tcscpy_s(pptcStrCnv[i], *sizeReturnValue, stringOrigin[i].c_str()); | ||
+ | #endif | ||
+ | } | ||
+ | |||
+ | //char出力 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | _tprintf(_T("%s\n"),*(pptcStrCnv + i)); | ||
+ | } | ||
+ | |||
+ | //動的確保変数の解放 | ||
+ | for(int i = 0;i < *pnStrArrayElement ;i++){ | ||
+ | delete[] *(pptcStrCnv + i); | ||
+ | } | ||
+ | delete[] pptcStrCnv; | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //・string→_bstr_t(マルチバイト文字) | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | _tprintf(_T("\n文字列の型変換string→_bstr_t\n")); | ||
+ | |||
+ | pbstrt_StrCnv = new _bstr_t[*pnStrArrayElement];//要素数分の大きさ+1を確保 | ||
+ | |||
+ | //変換 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | pbstrt_StrCnv[i] = stringOrigin[i].c_str(); | ||
+ | } | ||
+ | |||
+ | //出力 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | //無変換出力 | ||
+ | printf("%s\n",(char*)pbstrt_StrCnv[i]); | ||
+ | _tprintf(_T("%s\n"),(wchar_t*)pbstrt_StrCnv[i]); | ||
+ | } | ||
+ | |||
+ | //動的確保変数の解放 | ||
+ | delete[] pbstrt_StrCnv; | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //・string→CComBSTR(マルチバイト文字ワイド文字両対応 プロジェクト設定に従う) | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | _tprintf(_T("\n文字列の型変換string→CComBSTR\n")); | ||
+ | |||
+ | pccombstr_StrCnv = new CComBSTR[*pnStrArrayElement];//要素数分の大きさ+1を確保 | ||
+ | |||
+ | //変換 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | pccombstr_StrCnv[i] = stringOrigin[i].c_str(); | ||
+ | } | ||
+ | |||
+ | //出力 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | //char変換出力 | ||
+ | CW2A printstr(*(pccombstr_StrCnv + i)); | ||
+ | printf("%s\n",printstr); | ||
+ | //無変換出力 | ||
+ | _tprintf(_T("%s\n"),*(pccombstr_StrCnv + i)); | ||
+ | } | ||
+ | |||
+ | //動的確保変数の解放 | ||
+ | delete[] pccombstr_StrCnv; | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //・string→CStringA(マルチバイト文字) | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | _tprintf(_T("\n文字列の型変換string→CStringA\n")); | ||
+ | |||
+ | pcstringa_StrCnv = new CStringA[*pnStrArrayElement];//要素数分の大きさ+1を確保 | ||
+ | |||
+ | //変換 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | pcstringa_StrCnv[i] = stringOrigin[i].c_str(); | ||
+ | } | ||
+ | |||
+ | //出力 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | //char変換出力 | ||
+ | printf("%s\n",pcstringa_StrCnv[i]); | ||
+ | } | ||
+ | |||
+ | //動的確保変数の解放 | ||
+ | delete[] pcstringa_StrCnv; | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //・string→CStringW(ワイド文字) | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | _tprintf(_T("\n文字列の型変換string→CStringW\n")); | ||
+ | |||
+ | pcstringw_StrCnv = new CStringW[*pnStrArrayElement];//要素数分の大きさ+1を確保 | ||
+ | |||
+ | //変換 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | pcstringw_StrCnv[i] = stringOrigin[i].c_str(); | ||
+ | } | ||
+ | |||
+ | //出力 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | //wchar_t出力 | ||
+ | wprintf(L"%s\n",pcstringw_StrCnv[i]); | ||
+ | } | ||
+ | |||
+ | //動的確保変数の解放 | ||
+ | delete[] pcstringw_StrCnv; | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //・string→SystemString(マルチバイト文字) | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | _tprintf(_T("\n文字列の型変換string→SystemString\n")); | ||
+ | |||
+ | psysstring_StrCnv = gcnew array<String^>(*pnStrArrayElement); | ||
+ | //変換 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | char* pcStrTemp = new char[strlen(stringOrigin[i].c_str()) + 1]; | ||
+ | strcpy_s(pcStrTemp,strlen(stringOrigin[i].c_str()) + 1,stringOrigin[i].c_str()); | ||
+ | System::IntPtr ptr(pcStrTemp); | ||
+ | psysstring_StrCnv[i] = Marshal::PtrToStringAnsi(ptr); | ||
+ | } | ||
+ | |||
+ | //出力 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | //char変換出力 | ||
+ | printf("%s\n",psysstring_StrCnv[i]); | ||
+ | //TCHAR変換出力 | ||
+ | #ifdef UNICODE | ||
+ | _tprintf(_T("%s\n"),PtrToStringChars(psysstring_StrCnv[i])); | ||
+ | #else | ||
+ | _tprintf(_T("%s\n"),psysstring_StrCnv[i]); | ||
+ | #endif | ||
+ | } | ||
+ | |||
+ | //動的確保変数の解放 | ||
+ | delete[] psysstring_StrCnv; | ||
+ | </syntaxhighlight2> | ||
+ | <syntaxhighlight2 lang="cpp" line start="1"> | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //・SystemString→char | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | _tprintf(_T("\n文字列の型変換string→char\n")); | ||
+ | |||
+ | array<String^> ^sysstringOrigin = gcnew array<String^>{"SystemString型の変数 配列要素1","SystemString型の変数 配列要素2","SystemString型の変数 配列要素3"}; | ||
+ | |||
+ | printf("%d\n", sysstringOrigin->Length); | ||
+ | |||
+ | *pnStrArrayElement = sysstringOrigin->Length; | ||
+ | |||
+ | ppcStrCnv = new char*[*pnStrArrayElement];//要素数分の大きさ+1を確保 | ||
+ | |||
+ | //変換 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | pin_ptr<const wchar_t> wch = PtrToStringChars(sysstringOrigin[i]); | ||
+ | wcstombs_s(sizeReturnValue, NULL, 0,wch, 0); | ||
+ | ppcStrCnv[i] = new char[*sizeReturnValue]; | ||
+ | wcstombs_s(sizeReturnValue, ppcStrCnv[i], *sizeReturnValue, wch, *sizeReturnValue); | ||
+ | } | ||
+ | |||
+ | //char出力 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | printf("%s\n",*(ppcStrCnv + i)); | ||
+ | } | ||
+ | |||
+ | //動的確保変数の解放 | ||
+ | for(int i = 0;i < *pnStrArrayElement ;i++){ | ||
+ | delete[] *(ppcStrCnv + i); | ||
+ | } | ||
+ | delete[] ppcStrCnv; | ||
+ | |||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //・SystemString→TCHAR | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | _tprintf(_T("\n文字列の型変換SystemString→TCHAR\n")); | ||
+ | |||
+ | pptcStrCnv = new TCHAR*[*pnStrArrayElement];//要素数分の大きさ+1を確保 | ||
+ | |||
+ | //変換 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | |||
+ | #ifdef UNICODE | ||
+ | pin_ptr<const wchar_t> wch = PtrToStringChars(sysstringOrigin[i]); | ||
+ | *sizeReturnValue = _tcslen(wch) + 1; | ||
+ | pptcStrCnv[i] = new TCHAR[*sizeReturnValue]; | ||
+ | _tcscpy_s(pptcStrCnv[i], *sizeReturnValue, wch); | ||
+ | #else | ||
+ | pin_ptr<const wchar_t> wch = PtrToStringChars(sysstringOrigin[i]); | ||
+ | wcstombs_s(sizeReturnValue, NULL, 0,wch, 0); | ||
+ | pptcStrCnv[i] = new TCHAR[*sizeReturnValue]; | ||
+ | wcstombs_s(sizeReturnValue, pptcStrCnv[i], *sizeReturnValue, wch, *sizeReturnValue); | ||
+ | #endif | ||
+ | } | ||
+ | |||
+ | //char出力 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | _tprintf(_T("%s\n"),*(pptcStrCnv + i)); | ||
+ | } | ||
+ | |||
+ | //動的確保変数の解放 | ||
+ | for(int i = 0;i < *pnStrArrayElement ;i++){ | ||
+ | delete[] *(pptcStrCnv + i); | ||
+ | } | ||
+ | delete[] pptcStrCnv; | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //・SystemString→_bstr_t(マルチバイト文字) | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | _tprintf(_T("\n文字列の型変換SystemString→_bstr_t\n")); | ||
+ | |||
+ | pbstrt_StrCnv = new _bstr_t[*pnStrArrayElement];//要素数分の大きさ+1を確保 | ||
+ | |||
+ | //変換 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | pin_ptr<const wchar_t> wch = PtrToStringChars(sysstringOrigin[i]); | ||
+ | wcstombs_s(sizeReturnValue, NULL, 0,wch, 0); | ||
+ | char* pcStrTemp = new char[*sizeReturnValue]; | ||
+ | wcstombs_s(sizeReturnValue, pcStrTemp, *sizeReturnValue, wch, *sizeReturnValue); | ||
+ | pbstrt_StrCnv[i] = pcStrTemp; | ||
+ | } | ||
+ | |||
+ | //出力 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | //無変換出力 | ||
+ | printf("%s\n",(char*)pbstrt_StrCnv[i]); | ||
+ | _tprintf(_T("%s\n"),(wchar_t*)pbstrt_StrCnv[i]); | ||
+ | } | ||
+ | |||
+ | //動的確保変数の解放 | ||
+ | delete[] pbstrt_StrCnv; | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //・SystemString→CComBSTR(マルチバイト文字ワイド文字両対応 プロジェクト設定に従う) | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | _tprintf(_T("\n文字列の型変換SystemString→CComBSTR\n")); | ||
+ | |||
+ | pccombstr_StrCnv = new CComBSTR[*pnStrArrayElement];//要素数分の大きさ+1を確保 | ||
+ | |||
+ | //変換 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | pin_ptr<const wchar_t> wch = PtrToStringChars(sysstringOrigin[i]); | ||
+ | wcstombs_s(sizeReturnValue, NULL, 0,wch, 0); | ||
+ | char* pcStrTemp = new char[*sizeReturnValue]; | ||
+ | wcstombs_s(sizeReturnValue, pcStrTemp, *sizeReturnValue, wch, *sizeReturnValue); | ||
+ | pccombstr_StrCnv[i] = pcStrTemp; | ||
+ | } | ||
+ | |||
+ | //出力 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | //char変換出力 | ||
+ | CW2A printstr(*(pccombstr_StrCnv + i)); | ||
+ | printf("%s\n",printstr); | ||
+ | //無変換出力 | ||
+ | _tprintf(_T("%s\n"),*(pccombstr_StrCnv + i)); | ||
+ | } | ||
+ | |||
+ | //動的確保変数の解放 | ||
+ | delete[] pccombstr_StrCnv; | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //・SystemString→CStringA(マルチバイト文字) | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | _tprintf(_T("\n文字列の型変換SystemString→CStringA\n")); | ||
+ | |||
+ | pcstringa_StrCnv = new CStringA[*pnStrArrayElement];//要素数分の大きさ+1を確保 | ||
+ | |||
+ | //変換 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | pin_ptr<const wchar_t> wch = PtrToStringChars(sysstringOrigin[i]); | ||
+ | wcstombs_s(sizeReturnValue, NULL, 0,wch, 0); | ||
+ | char* pcStrTemp = new char[*sizeReturnValue]; | ||
+ | wcstombs_s(sizeReturnValue, pcStrTemp, *sizeReturnValue, wch, *sizeReturnValue); | ||
+ | pcstringa_StrCnv[i] = pcStrTemp; | ||
+ | } | ||
+ | |||
+ | //出力 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | //char変換出力 | ||
+ | printf("%s\n",pcstringa_StrCnv[i]); | ||
+ | } | ||
+ | |||
+ | //動的確保変数の解放 | ||
+ | delete[] pcstringa_StrCnv; | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //・SystemString→CStringW(ワイド文字) | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | _tprintf(_T("\n文字列の型変換SystemString→CStringW\n")); | ||
+ | |||
+ | pcstringw_StrCnv = new CStringW[*pnStrArrayElement];//要素数分の大きさ+1を確保 | ||
+ | |||
+ | //変換 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | pin_ptr<const wchar_t> wch = PtrToStringChars(sysstringOrigin[i]); | ||
+ | wcstombs_s(sizeReturnValue, NULL, 0,wch, 0); | ||
+ | char* pcStrTemp = new char[*sizeReturnValue]; | ||
+ | wcstombs_s(sizeReturnValue, pcStrTemp, *sizeReturnValue, wch, *sizeReturnValue); | ||
+ | pcstringw_StrCnv[i] = pcStrTemp; | ||
+ | } | ||
+ | |||
+ | //出力 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | //wchar_t出力 | ||
+ | wprintf(L"%s\n",pcstringw_StrCnv[i]); | ||
+ | } | ||
+ | |||
+ | //動的確保変数の解放 | ||
+ | delete[] pcstringw_StrCnv; | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //・SystemString→string(マルチバイト文字) | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | _tprintf(_T("\n文字列の型変換SystemString→string\n")); | ||
+ | |||
+ | pstring_StrCnv = new string[*pnStrArrayElement];//要素数分の大きさ+1を確保 | ||
+ | |||
+ | //変換 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | pin_ptr<const wchar_t> wch = PtrToStringChars(sysstringOrigin[i]); | ||
+ | wcstombs_s(sizeReturnValue, NULL, 0,wch, 0); | ||
+ | char* pcStrTemp = new char[*sizeReturnValue]; | ||
+ | wcstombs_s(sizeReturnValue, pcStrTemp, *sizeReturnValue, wch, *sizeReturnValue); | ||
+ | pstring_StrCnv[i] = pcStrTemp; | ||
+ | } | ||
+ | |||
+ | //出力 | ||
+ | for(int i = 0; i < *pnStrArrayElement; i++){ | ||
+ | //char変換出力 | ||
+ | printf("%s\n",pstring_StrCnv[i].c_str()); | ||
+ | } | ||
+ | |||
+ | //動的確保変数の解放 | ||
+ | delete[] pstring_StrCnv; | ||
+ | </syntaxhighlight2> | ||
+ | |||
+ | と、こんな感じです。もっと効率の良い変換があったらごめんなさい。動的に必要最小限のメモリを確保させながらの処理だとこんな感じになるよっていう例になっていると思います。プログラムによっては、配列の大きさを固定したっていいわけです。その方がコーディングや変数管理が楽になる場合もあります。この章に関しては以上です。既に準備されている型の変換なんてのは、変換するための関数が準備されているので、比較的簡単な技術になります。全角半角変換や文字コード変換処理を実際に組む方が難しいかもしれません。それもおいおい記述したいと思います。 | ||
※2014/09/21 ここまでで、疲れたから、また暫くオヤスミ。次に気が向くのはいつになるのか、誰も知らない。 | ※2014/09/21 ここまでで、疲れたから、また暫くオヤスミ。次に気が向くのはいつになるのか、誰も知らない。 | ||
=='''文字列文字コード変換'''== | =='''文字列文字コード変換'''== | ||
+ | 文字コード変換は、標準関数だけでは実現できない変換になっています。自分で変換関数を作るのもありですが、既にきちんと作られた変換ライブラリが無償で配布されています。変換処理自体を作成するには、文字コードの体系の理解やエンコーディングの理解が必要です。そして、それに対応する変換処理を作るわけです。ShiftJIS CP932とUnicode UTF-16はマルチバイトとワイド文字の変換によって実現できますので、UTF-8やEUCあるいはJISといった変換には変換処理の作成が必要になってきます。更に同じUnicodeでもUTF-16やUTF-32ではリトルエンディアン方式、ビッグエンディアン方式さらにはBOM(ByteOrderMark)の付加といった変換を考慮する必要もあります。UTF-16やUTF-32では常に複数Byteで一文字が表現され、その複数バイト塊のメモリアドレスの番地の小さい方から文字コードの上位バイトの情報をいれるビッグエンディアンと番地の小さい方に下位バイトの情報をいれていくリトルエンディアンがあり、その文字コードファイルの先頭2ByteにBOMという符号で、どっちの方式が使われているのかを示すものです。先頭アドレスからFF FE と格納されていればビッグエンディアン、FE FF と格納されていればリトルエンディアンであることを示します。あえてBOMを付与しないで、プログラムがどっちの文字コードが使われているか解析する方法や文書を閲覧する都度、ユーザが選択する方法もあります。UTF-8では、複数バイト使われるときには徐々にバイト数が大きくなる可変長の方式をとっていて、リトルエンディアンとかビッグエンディアンという概念がないため、BOMは不要ですが、付与するパターンもゆるされており、BOMありで統一してテキストを作成している人もいることから無意味なBOM付きファイルも存在します。また、このBOMが原因でファイルの読み取りに失敗してしまうUTF-8採用のプログラムも多いようです。どっちのファイルも読み取れるプログラムを作るのが良いですが、BOMありでは動作しないものと割りきって、BOM付きUTF-8を切り捨てていくプログラム作成者もいるように思います。こうすることでBOM付きUTF-8を撲滅することになっているのかもしれません。自分もUTF-8にはBOMは不要だと感じています。あえてBOMを付けれる出力のサポートも必要だと思うし、読み取れるようにもしときたいものですね。そんなプログラム作ったことないですけど…。 | ||
+ | |||
+ | |||
+ | ちなみにVisualStudioのコード編集エディタはデフォルトでは、ShiftJIS CP932が利用されます。変更するには、メニューのファイル(F)-保存オプションの詳細設定のエンコード欄の値を変えることで実現できます。行の終わり欄で改行コードも変更できます。特別にテキストの中で特定の文字コードセットのリテラルを使う必要がある以外は基本はShiftJIS CP932でいいのではないでしょうか?L""リテラルでUnicodeも使えますし。 | ||
+ | |||
+ | |||
+ | こういった文字コードの変換は、自分のプログラムだけで動作するのではなく、外部におかれた情報を読み込む、あるいは書き換えるといった動作をする場合に必要になってきます。固定の外部ファイルとのやりとりであれば、変換が発生しないように構築すると必要ないし、変換が必要であっても1種類の変換で済みます。ありとあらゆる場所からテキストを読むこむようなプログラムになると、この文字コード変換を網羅しないと利便性が損なわれる結果になります。文字コードの掃出し処理が間違っていると、文字コード破壊プログラムになってしまう可能性もありますので、自分で変換処理を作って、書き出すプログラムを作るのはかなりの知識を必要とします。実績のある変換処理ライブラリを使った方が安全です。速度改善の必要があるような人は自分で変換処理作りに挑むのもよいのかもしれません。ここでは、既存の変換処理ライブラリを使う方法を示し、時間があれば具体的な変換処理の作成について触れたいと思います。 | ||
+ | |||
+ | |||
+ | 例によって、全部のサンプルを記事に書き起こすまでに相当な時間がかかると思いますので、すこしづつ進めていくことになると思います。 | ||
+ | |||
+ | |||
+ | C++/CLIだとEncodingというライブラリを使うことで変換ができますが、C++以下の範囲で扱う場合はIBM社が作成したオープンソースICU(International Components for Unicode)、GNUプロジェクトによって作られLGPLのICONVというライブラリがあります。ほかにも有志によって作られたフリーソフトnkf.dllというライブラリを使う方法もあります。ここではICUを使った方法について記述します。GNUは自由に使うことのできるUnixとしてのOSであるLinuxの開発プロジェクトで、GNU's Not Unixという意味だそうです。そうすると先頭にまたGNUが出てくるから、それは何の意味?ってなるとまたGNUはGNU's Not Unixって略語だよっていう風になる再帰的な略語です。GNUのGの意味は思考を停止しない限り永遠に再帰されます。LGPL(Lesser General Public License)は簡単に表現するとコンパイルするプログラムの配布には関与しないライセンスですが、ライブラリそのものや、制限に関するライセンスの詳細な意味についてはGNUプロジェクトによる説明で解釈して下さい。 | ||
+ | |||
+ | |||
+ | ICUはC++(Cpp)の技術を含むプロジェクトですので、C言語の領域からは外れます。C言語だけで、文字コード変換をやろうとすると、このようなライブラリがないために、もっと基礎的なコード変換技術を身に着ける必要があります。根本的な言語でやる方が敷居が高いというのはアセンブラ含めて、同様の事だと言えると思います。ここではそのような基礎的な技術は紹介しないので、C言語だけで実現する必要がある場合には、ICUプロジェクトのソースを解析するなりして、クラスやC++で登場する構文をを使わない形式で実現できるように挑戦してみると良いです。とても大変なことだと思います。 | ||
+ | |||
+ | |||
+ | ICUのWebSite<br /> | ||
+ | http://site.icu-project.org/<br /> | ||
+ | まずここから最新のソースファイルをダウンロードします。<br /> | ||
+ | 執筆時点'14/09ではICU Versionは5.4で、VisualStudio2012を使っている分には、現在のICU4CのソースはCygwinも必要とせずにビルドができます。VisualStudio2010で作られているので、初回のソューションファイルオープンでプロジェクトの変換が必要になります。ビルド後VisualStudioの設定も以下のとおり実施する必要があります。ICUが利用している開発環境よりも新しいものなら楽にビルドできそうです。 | ||
+ | |||
+ | |||
+ | *ビルドの手順 | ||
+ | :1.環境変数PATHに[icu配置パス]\icu\bin を追加。x64プロジェクトをビルドするときは[icu配置パス]\icu\bin64っすかね。 | ||
+ | :2.[icu配置パス]\icu\source\allinone\allinone.sln を開く(プロジェクト変換ダイアログ表示されたらOKで変換する) | ||
+ | ::注)icu配置パスを決めてからビルドをしないと駄目です。ビルド時に生成されるファイルで絶対パスで管理されるDATAがあるため、ビルド後に移動させると動かなくなります。 | ||
+ | :3.メニューの[ビルド]-[バッチビルド]を選択し、表示されたダイアログで、Win32かx64のプロジェクトを選択してから→[ビルド]で、ひたすら待つ。全部でおそらく15分(Corei7 3610QM 2.3GHz)くらい | ||
+ | ::次のプロジェクト設定Win32 or x64をビルドするときには手順1に戻ることになります。 | ||
+ | :4.コマンドプロンプトでテストプログラムを動かす。テストコマンドの引数4種類全部確かめるなら以下4つのコマンド全部実行。それか自分の目的のテストだけ実施。あるいはテストはやらないのもひとつの選択肢。 | ||
+ | ::*[icu配置パス]\icu\source\allinone\allinone.bat x86 Debug | ||
+ | ::*[icu配置パス]\icu\source\allinone\allinone.bat x86 Release | ||
+ | ::*[icu配置パス]\icu\source\allinone\allinone.bat x64 Debug | ||
+ | ::*[icu配置パス]\icu\source\allinone\allinone.bat x64 Release | ||
+ | |||
+ | |||
+ | ソースを見ることができるのですが、とにかく巨大なプロジェクトで、ソースを見るのも勉強になるかもしれません。巨大プロジェクトならではのアイデア満載かなぁと思います。ワーニングもいっぱいだけど、まぁ気にしない。バグもあるみたいで、同時に配布されるテストプログラムをビルド後に動作させてみるのですが、うまく動かない関数もありました。今回の目的にはあまり関係してこない部分のバグだと思うので、このまま使ってみます。 | ||
+ | |||
+ | |||
+ | 以下、テスト時のエラーログです。ひょっとしたら自分だけなのかもしれませんが、既知のバグみたいな?いやテストだけで出るエラーみたいな感じなので気にしないことにします。え?ホントにそれでいいのか?調べるのも面倒だし、放置。 | ||
+ | <syntaxhighlight2 lang="text"> | ||
+ | KNOWN ISSUES | ||
+ | #11217 <http://bugs.icu-project.org/trac/ticket/11217> | ||
+ | /tsutil/cldrtest/TestExemplarSet | ||
+ | "Fix result of uscript_getCode for yi: USCRIPT_YI -> USCRIPT_HEBREW" | ||
+ | /tsutil/cldrtest/VerifyTranslation | ||
+ | "Fix result of uscript_getCode for yi: USCRIPT_YI -> USCRIPT_HEBREW" | ||
+ | (To run suppressed tests, use the -K option.) | ||
+ | |||
+ | |||
+ | SUMMARY: | ||
+ | ******* [Total error count: 590] | ||
+ | Errors in | ||
+ | [/tsconv/nucnvtst/TestISO_2022_JP] | ||
+ | [/tsconv/nucnvtst/TestJIS] | ||
+ | [/tsconv/nucnvtst/TestISO_2022_JP_1] | ||
+ | [/tsconv/nucnvtst/TestISO_2022_JP_2] | ||
+ | [/tsconv/nucnvtst/TestHZ] | ||
+ | [/tsconv/nucnvtst/TestJitterbug2346] | ||
+ | [/tsconv/nccbtst/TestSkipCallBack] | ||
+ | [/tsconv/nccbtst/TestSubWithValueCallBack] | ||
+ | [/tsconv/ncnvtst/TestResetBehaviour] | ||
+ | </syntaxhighlight2> | ||
+ | 表:icucheck.bat Win32 Release のテスト結果でのエラー | ||
+ | |||
+ | |||
+ | あらゆる文字コードの変換だけでなく、大文字小文字相互変換、全角半角相互変換、ひらがなカタカナ相互変換、他にもひらがなやカタカナからのローマ字相互変換といった複雑な変換も提供しています。そのほかにも通貨フォーマットや時間表記変換といった面白い変換も組み込まれています。ここでは文字コード変換のみを取り上げます。文字コードをファイルに出力するのはもっとあとで説明する予定なので、ここでは、サンプルとなる文字列をその文字コード体系に合わせて16進数で表現した配列として扱い、それを基に変換後の文字コード配列が生成されるのを確かめます。変換後の文字コードがUNICODEやShiftJIS以外になる場合も同じく16進数で表現される配列で示します、逆に異なる文字コードから基に戻す変換も確認します。 | ||
+ | |||
+ | |||
+ | *プロジェクトの設定 | ||
+ | :1.Win32プロジェクトなら[icu配置パス]\icu\bin、x64プロジェクトなら[icu配置パス]\icu\bin64という絶対パスを、プロジェクト毎にプロジェクトの設定の中(ALT+F7キーで表示されるダイアログの構成プロパティの中)にあるVCディレクトリの実行可能ファイルディレクトリにパスを設定する。Win32プロジェクトとx64プロジェクトとでパスは異なるためプロジェクト毎に毎回設定した方が良いでしょう。文字コード変換を必要とするプロジェクトを作成する都度、設定しましょう。面倒な人でWin32プロジェクトしか作らないX54しか作らないという人は、どちらかの環境変数PATHに入れてもいいでしょう。でも結局、この次にlibファイルやincludeファイルの設定もしないといけないし、やっぱりプロジェクト毎に設定しましょう。一見、面倒そうだけど、そんなにたくさんプロジェクト作る人ってあんまりいないと思います。小さなサンプルコードプロジェクトをたくさん作って、それで変換テストしまくる人は大変かもしれませんね。自分は基本Win32のプロジェクトで遊んでるので、環境変数PATHにWin32プロジェクト用の実行パスを登録しています。X64をビルドするときに、また切り替えます。このとき、新しいパス変数を作ってPATH32=[icu配置パス]\icu\bin;(他のSDKの実行パス);…;…でPATH64=[icu配置パス]\icu\bin64;(他のSDKの実行パス);…;…として、環境変数PATHにはPATH=(既存パス1);(既存パス2);%PATH32%;(既存パスn)みたいに登録するといろいろなSDKをまとめて切り替えられます。64に変えればいいんだもんね。 | ||
+ | :2.Win32プロジェクトなら[icu配置パス]\icu\lib、x64プロジェクトなら[icu配置パス]\icu\lib64という絶対パスをプロジェクト毎にプロジェクトの設定の中にあるVCディレクトリのライブラリディレクトリにパスを設定する。これも実行パス同様に管理して環境変数LIB32とLIB64を作って、環境変数LIB=%LIB32%とかにすると、プロジェクトの設定にはライブラリの欄に$(LIB)と入力するだけでよくなります。 | ||
+ | :3.Win32,x64共通ですが、[icu配置パス]\icu\includeをプロジェクト毎にプロジェクトの設定の中にあるVCディレクトリのインクルードディレクトリに設定します。自分はこれも環境変数INCLUDEを作っていて、$(INCLUDE)と設定しています。 | ||
+ | :4.デバッグプロジェクトならicuucd.lib、リリースプロジェクトならicuuc.libという追加するべきライブラリ名をプロジェクト毎にプロジェクトの設定の中にあるリンカー-入力の追加の依存ファイル欄に追記します。 | ||
+ | |||
+ | |||
+ | このICUはC++/CLIプロジェクトのような/clrオプションコンパイルには対応していません。UConverterという構造体が実態が未定義のまま利用されていますが、このような宣言がされているだけのものをビルドするとリンカーエラーが発生し、プログラムは動作しません。対処方法はあると思いますが、ICUはとてつもなく大きなプロジェクトファイルです。C++/CLIで使っていくには、現在のバージョンを永続的に使っていくのか?メンテしきれるか?どうかも含めた検討が必要になります。 | ||
+ | |||
+ | |||
+ | リンカー ツールの警告 LNK4248 http://msdn.microsoft.com/ja-jp/library/h8027ys9.aspx | ||
+ | |||
+ | |||
+ | プロジェクトの設定は以上です。以下が実際の変換サンプルになります。これまでのサンプルもそうですが、実際にはサポートクラスを作って、毎回新しく変数定義しているものは、クラスを呼ぶたびにまとめて生成されるようなセットを作るべきです。変換サポートクラスの作り方については、クラスに関する記述を掘り下げるセクションで触れたいと思いますが、ここでは例のごとく直線的なプログラムになっています。 | ||
+ | <syntaxhighlight2 lang="cpp" line start="1"> | ||
+ | #include "stdafx.h" | ||
+ | #include <unicode/ucnv.h> | ||
+ | #include <stdlib.h> | ||
+ | #include <string> | ||
+ | #include <mbstring.h> | ||
+ | #include <iostream> | ||
+ | #include <locale> | ||
+ | #include <tchar.h> | ||
+ | #include "atlstr.h"//CString,CStringA,CStringWおよびLPTSTR,LPWSTR,LPSTR,LPCTSTR,LPCWSTR,LPCSTRの定義プリプロセッサ | ||
+ | #include "cstringt.h"//CStringTの定義プリプロセッサ | ||
+ | #include "atlbase.h" | ||
+ | #include "comutil.h" | ||
+ | using namespace std; | ||
+ | |||
+ | int _tmain(int argc, _TCHAR* argv[]) | ||
+ | { | ||
+ | _tsetlocale(LC_ALL, _T("Japanese")); | ||
+ | |||
+ | |||
+ | |||
+ | // "JIS文字列" のJIS(iso-2022-jp)表現↓ | ||
+ | string jis = "\x4A\x49\x53\x1B\x24\x42\x4A\x38\x3B\x7A\x4E\x73\x1B\x28\x42"; | ||
+ | wstring wstr = L"JIS文字列"; | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | // JIS → UNICODE | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | UConverter* ucnvTest; | ||
+ | UErrorCode uerrorNum; | ||
+ | int nStrSize; | ||
+ | int nStrResultSize; | ||
+ | nStrSize = jis.size(); | ||
+ | |||
+ | std::wstring stringCnvResult(nStrSize, L'\0'); | ||
+ | |||
+ | ucnvTest = ucnv_open("iso-2022-jp", &uerrorNum); | ||
+ | nStrResultSize = ucnv_toUChars( | ||
+ | ucnvTest, | ||
+ | &stringCnvResult[0], stringCnvResult.size(), // 変換先のポインタとサイズ | ||
+ | &jis[0], nStrSize, // 変換元のポインタとサイズ | ||
+ | &uerrorNum | ||
+ | ); | ||
+ | stringCnvResult.resize(nStrResultSize); | ||
+ | ucnv_close(ucnvTest); | ||
+ | _tprintf(_T("%s\n"), stringCnvResult.c_str()); | ||
+ | |||
+ | |||
+ | wchar_t* pwcStr = new wchar_t[_tcslen(stringCnvResult.c_str()) + 1]; | ||
+ | _tcscpy_s(pwcStr,_tcslen(stringCnvResult.c_str()) + 1,stringCnvResult.c_str()); | ||
+ | for(int i = 0;i < (int)_tcslen(stringCnvResult.c_str());i++){ | ||
+ | printf("%04x:",*(pwcStr + i)); | ||
+ | } | ||
+ | printf("\n"); | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | // UNICODE → JIS | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | ucnvTest = ucnv_open("iso-2022-jp", &uerrorNum); | ||
+ | |||
+ | nStrSize = wstr.size(); | ||
+ | std::string stringCnvResult2(ucnv_getMaxCharSize(ucnvTest) * nStrSize , L'\0'); | ||
+ | |||
+ | |||
+ | nStrResultSize = ucnv_fromUChars( | ||
+ | ucnvTest, | ||
+ | &stringCnvResult2[0], stringCnvResult2.size(), // 変換先のポインタとサイズ | ||
+ | &wstr[0], nStrSize, // 変換元のポインタとサイズ | ||
+ | &uerrorNum | ||
+ | ); | ||
+ | stringCnvResult2.resize(nStrResultSize); | ||
+ | ucnv_close(ucnvTest); | ||
+ | _tprintf(_T("%s\n"), stringCnvResult2.c_str()); | ||
+ | |||
+ | |||
+ | char* pcStr = new char[strlen(stringCnvResult2.c_str()) + 1]; | ||
+ | strcpy_s(pcStr,strlen(stringCnvResult2.c_str()) + 1,stringCnvResult2.c_str()); | ||
+ | for(int i = 0;i < (int)strlen(stringCnvResult2.c_str());i++){ | ||
+ | printf("%02x:",*(pcStr + i)); | ||
+ | } | ||
+ | printf("\n"); | ||
+ | |||
+ | |||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | // UNICODE → SJIS | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | ucnvTest = ucnv_open("shift_jis", &uerrorNum); | ||
+ | |||
+ | nStrSize = wstr.size(); | ||
+ | std::string stringCnvResult3(ucnv_getMaxCharSize(ucnvTest) * nStrSize , L'\0'); | ||
+ | |||
+ | |||
+ | nStrResultSize = ucnv_fromUChars( | ||
+ | ucnvTest, | ||
+ | &stringCnvResult3[0], stringCnvResult3.size(), // 変換先のポインタとサイズ | ||
+ | &wstr[0], nStrSize, // 変換元のポインタとサイズ | ||
+ | &uerrorNum | ||
+ | ); | ||
+ | stringCnvResult3.resize(nStrResultSize); | ||
+ | ucnv_close(ucnvTest); | ||
+ | printf("%s\n", stringCnvResult3.c_str()); | ||
+ | |||
+ | |||
+ | char* pcStr2 = new char[strlen(stringCnvResult3.c_str()) + 1]; | ||
+ | strcpy_s(pcStr2,strlen(stringCnvResult3.c_str()) + 1,stringCnvResult3.c_str()); | ||
+ | for(int i = 0;i < (int)strlen(stringCnvResult3.c_str());i++){ | ||
+ | printf("%02x:",0x000000ff & *(pcStr2 + i)); | ||
+ | } | ||
+ | printf("\n"); | ||
+ | |||
+ | |||
+ | return 0; | ||
+ | } | ||
+ | </syntaxhighlight2> | ||
+ | という具合に変換すると結果として | ||
+ | <syntaxhighlight2 lang="text"> | ||
+ | JIS文字列 | ||
+ | 004a:0049:0053:6587:5b57:5217: | ||
+ | ????稻獎?B | ||
+ | 4a:49:53:1b:24:42:4a:38:3b:7a:4e:73:1b:28:42: | ||
+ | JIS文字列 | ||
+ | 4a:49:53:95:b6:8e:9a:97:f1: | ||
+ | |||
+ | </syntaxhighlight2> | ||
+ | のようなものが得られます。 | ||
+ | |||
+ | |||
+ | これですべての変換が出来そうな気分ですが、実際にはshift_jisコード上で展開される携帯電話各社の絵文字があったり、UNICODE上での文字の重複による変換先の最適化、UNICODEにしかない文字の変換があった場合の処理など実際のプログラミング技術が、ここをスタート地点として、広がっています。auとDocomoは絵文字を統一させたんだったかも…ソフトバンクはかなり独自の体系を維持。ウィルコム。イーモバ…ふむ、どうなってるんだろ。んで、UNICODEにも少し絵文字が追加されてたり…。でも結局、それを表示するのはその文字コードのグリフをもったフォントファイルなわけです。やれる範囲。結構、限られてます。特殊文字には、年号とかもあります。次の年号の文字コードとかも、後で変更追加になるに違いない。㍻。←平成を一文字で表した環境依存文字。文字コードの世界が今のようになった歴史を知るのも面白いですし、これからの文字コードはどうあるべきかを議論する国際的なワーキンググループも活動しています。絶賛迷走中あるいは理想形へ向かって進行中です。メールで半角カタカナが使えないのはJISコード iso-2022-jpのおかげです。更にはメールはBase64という変換方式もあり、バイナリーコードや文字列コードを先頭から6ビットずつ4セットにしていくエンコードがあります。こうやってメールはおくられているんだなと感心したものです。http://ja.wikipedia.org/wiki/Base64 | ||
+ | |||
+ | |||
+ | 上記のサンプルですが、動作しますが、ucnv_openでエラーコードが返ってきています。-122だそうで調べてみるとAMBIGUOUS_ALIAS_WARNING(-122) This converter alias can go to different converter implementations.とのことです。ワーニングレベルと認識できますが、他の方法で実装できるよだって。どういうこと? | ||
+ | |||
+ | |||
+ | 対応している変換は以下の文字コードになります。一番左が基本文字セット名で、その横にエイリアス名の個数、★の横にスペース区切りで全エイリアス名(別名)を記載しました。ucnv_open関数などの第一引数にはこのエイリアス名を大文字小文字の区別なく記載することができるようです。 | ||
+ | |||
+ | |||
+ | shift_jisは41行目と42行目でダブって登場しますね。ibm-943も。どっちが使われる?調べるの?いやいや、調べきれそうもないです。よくみかけるコード名でいくと上側が使われるべきなんでしょうけど。どっちもそれほど変わらないのか、それとも、これが俗にいうマイクロソフトsjisとsjisの違いなのか?Windowsなら上で、それ以外は純粋なShift_JISってことなのか。AMBIGUOUS_ALIAS_WARNINGの原因にはあいまいな変換がされたことに由来するらしいが、どうも、指定方法の問題ではないらしい。謎は謎のままに。謎というよりはICUの英語を理解できないだけだが…。だからどうしろとは言わない説明書がうらめしい。 | ||
+ | |||
+ | |||
+ | ibm-943_P15A-2003 19 ★ibm-943_P15A-2003 ibm-943 '''Shift_JIS''' MS_Kanji csShiftJIS windows-31j csWindows31J x-sjis x-ms-cp932 '''cp932''' windows-93cp943c IBM-943C ms932 pck '''sjis''' ibm-943_VSUB_VPUA x-MS932_0213 x-JISAutoDetect | ||
+ | |||
+ | ibm-943_P130-1999 7 ★ibm-943_P130-1999 ibm-943 '''Shift_JIS''' cp943 943 ibm-943_VASCII_VSUB_VPUA x-IBM943 | ||
+ | <syntaxhighlight2 lang="text" line start="1"> | ||
+ | UTF-8 14 ★UTF-8 ibm-1208 ibm-1209 ibm-5304 ibm-5305 ibm-13496 ibm-13497 ibm-17592 ibm-17593 windows-65001 cp1208 x-UTF_8J unicode-1-1-utf unicode-2-0-utf-8 | ||
+ | UTF-16 7 ★UTF-16 ISO-10646-UCS-2 ibm-1204 ibm-1205 unicode csUnicode ucs-2 | ||
+ | UTF-16BE 21 ★UTF-16BE x-utf-16be UnicodeBigUnmarked ibm-1200 ibm-1201 ibm-13488 ibm-13489 ibm-17584 ibm-17585 ibm-21680 ibm-21681 ibm-257 ibm-25777 ibm-29872 ibm-29873 ibm-61955 ibm-61956 windows-1201 cp1200 cp1201 UTF16_BigEndian | ||
+ | UTF-16LE 17 ★UTF-16LE x-utf-16le UnicodeLittleUnmarked ibm-1202 ibm-1203 ibm-13490 ibm-13491 ibm-17586 ibm-17587 ibm-21682 ibm-21683 ibm-778 ibm-25779 ibm-29874 ibm-29875 UTF16_LittleEndian windows-1200 | ||
+ | UTF-32 6 ★UTF-32 ISO-10646-UCS-4 ibm-1236 ibm-1237 csUCS4 ucs-4 | ||
+ | UTF-32BE 5 ★UTF-32BE UTF32_BigEndian ibm-1232 ibm-1233 ibm-9424 | ||
+ | UTF-32LE 4 ★UTF-32LE UTF32_LittleEndian ibm-1234 ibm-1235 | ||
+ | UTF16_PlatformEndian 1 ★UTF16_PlatformEndian | ||
+ | UTF16_OppositeEndian 1 ★UTF16_OppositeEndian | ||
+ | UTF32_PlatformEndian 1 ★UTF32_PlatformEndian | ||
+ | UTF32_OppositeEndian 1 ★UTF32_OppositeEndian | ||
+ | UTF-16BE,version=1 2 ★UTF-16BE,version=1 UnicodeBig | ||
+ | UTF-16LE,version=1 3 ★UTF-16LE,version=1 UnicodeLittle x-UTF-16LE-BOM | ||
+ | UTF-16,version=1 1 ★UTF-16,version=1 | ||
+ | UTF-16,version=2 1 ★UTF-16,version=2 | ||
+ | UTF-7 4 ★UTF-7 windows-65000 unicode-1-1-utf-7 unicode-2-0-utf-7 | ||
+ | IMAP-mailbox-name 1 ★IMAP-mailbox-name | ||
+ | SCSU 3 ★SCSU ibm-1212 ibm-1213 | ||
+ | BOCU-1 4 ★BOCU-1 csBOCU-1 ibm-1214 ibm-1215 | ||
+ | CESU-8 2 ★CESU-8 ibm-9400 | ||
+ | ISO-8859-1 11 ★ISO-8859-1 ibm-819 IBM819 cp819 latin1 8859_1 csISOLatin1 iso-ir-100 ISO_8859-1:1987 l1 819 | ||
+ | US-ASCII 16 ★US-ASCII ASCII ANSI_X3.4-1968 ANSI_X3.4-1986 ISO_646.irv:1991 iso_646.irv:1983 ISO646-US us csASCII iso-ir-6 cp367 ascii7 64 | ||
+ | windows-20127 ibm-367 IBM367 | ||
+ | gb18030 4 ★gb18030 ibm-1392 windows-54936 GB18030 | ||
+ | ibm-912_P100-1995 12 ★ibm-912_P100-1995 ibm-912 ISO-8859-2 ISO_8859-2:1987 latin2 csISOLatin2 iso-ir-101 l2 8859_2 cp912 912 windows-2859 | ||
+ | ibm-913_P100-2000 12 ★ibm-913_P100-2000 ibm-913 ISO-8859-3 ISO_8859-3:1988 latin3 csISOLatin3 iso-ir-109 l3 8859_3 cp913 913 windows-2859 | ||
+ | ibm-914_P100-1995 12 ★ibm-914_P100-1995 ibm-914 ISO-8859-4 latin4 csISOLatin4 iso-ir-110 ISO_8859-4:1988 l4 8859_4 cp914 914 windows-2859 | ||
+ | ibm-915_P100-1995 11 ★ibm-915_P100-1995 ibm-915 ISO-8859-5 cyrillic csISOLatinCyrillic iso-ir-144 ISO_8859-5:1988 8859_5 cp915 915 window28595 | ||
+ | ibm-1089_P100-1995 16 ★ibm-1089_P100-1995 ibm-1089 ISO-8859-6 arabic csISOLatinArabic iso-ir-127 ISO_8859-6:1987 ECMA-114 ASMO-708 8859_6p1089 1089 windows-28596 ISO-8859-6-I ISO-8859-6-E x-ISO-8859-6S | ||
+ | ibm-9005_X110-2007 13 ★ibm-9005_X110-2007 ibm-9005 ISO-8859-7 8859_7 greek greek8 ELOT_928 ECMA-118 csISOLatinGreek iso-ir-126 ISO_8859-7987 windows-28597 sun_eu_greek | ||
+ | ibm-813_P100-1995 4 ★ibm-813_P100-1995 ibm-813 cp813 813 | ||
+ | ibm-5012_P100-1999 12 ★ibm-5012_P100-1999 ibm-5012 ISO-8859-8 hebrew csISOLatinHebrew iso-ir-138 ISO_8859-8:1988 ISO-8859-8-I ISO-8859-8-8859_8 windows-28598 hebrew8 | ||
+ | ibm-916_P100-1995 4 ★ibm-916_P100-1995 ibm-916 cp916 916 | ||
+ | ibm-920_P100-1995 15 ★ibm-920_P100-1995 ibm-920 ISO-8859-9 latin5 csISOLatin5 iso-ir-148 ISO_8859-9:1989 l5 8859_9 cp920 920 windows-2859ECMA-128 turkish8 turkish | ||
+ | iso-8859_10-1998 7 ★iso-8859_10-1998 ISO-8859-10 iso-ir-157 l6 ISO_8859-10:1992 csISOLatin6 latin6 | ||
+ | iso-8859_11-2001 4 ★iso-8859_11-2001 ISO-8859-11 thai8 x-iso-8859-11 | ||
+ | ibm-921_P100-1995 8 ★ibm-921_P100-1995 ibm-921 ISO-8859-13 8859_13 windows-28603 cp921 921 x-IBM921 | ||
+ | iso-8859_14-1998 7 ★iso-8859_14-1998 ISO-8859-14 iso-ir-199 ISO_8859-14:1998 latin8 iso-celtic l8 | ||
+ | ibm-923_P100-1998 13 ★ibm-923_P100-1998 ibm-923 ISO-8859-15 Latin-9 l9 8859_15 latin0 csisolatin0 csisolatin9 iso8859_15_fdis cp923 923 wdows-28605 | ||
+ | ibm-942_P12A-1999 10 ★ibm-942_P12A-1999 ibm-942 ibm-932 cp932 shift_jis78 sjis78 ibm-942_VSUB_VPUA ibm-932_VSUB_VPUA x-IBM942 x-IBM942C | ||
+ | ibm-943_P15A-2003 19 ★ibm-943_P15A-2003 ibm-943 Shift_JIS MS_Kanji csShiftJIS windows-31j csWindows31J x-sjis x-ms-cp932 cp932 windows-93cp943c IBM-943C ms932 pck sjis ibm-943_VSUB_VPUA x-MS932_0213 x-JISAutoDetect | ||
+ | ibm-943_P130-1999 7 ★ibm-943_P130-1999 ibm-943 Shift_JIS cp943 943 ibm-943_VASCII_VSUB_VPUA x-IBM943 | ||
+ | ibm-33722_P12A_P12A-2009_U2 5 ★ibm-33722_P12A_P12A-2009_U2 ibm-33722 ibm-5050 ibm-33722_VPUA IBM-eucJP | ||
+ | ibm-33722_P120-1999 9 ★ibm-33722_P120-1999 ibm-33722 ibm-5050 cp33722 33722 ibm-33722_VASCII_VPUA x-IBM33722 x-IBM33722A x-IBM33722C | ||
+ | ibm-954_P101-2007 4 ★ibm-954_P101-2007 ibm-954 x-IBM954 x-IBM954C | ||
+ | euc-jp-2007 7 ★euc-jp-2007 EUC-JP Extended_UNIX_Code_Packed_Format_for_Japanese csEUCPkdFmtJapanese X-EUC-JP eucjis ujis | ||
+ | ibm-1373_P100-2002 3 ★ibm-1373_P100-2002 ibm-1373 windows-950 | ||
+ | windows-950-2000 7 ★windows-950-2000 Big5 csBig5 windows-950 x-windows-950 x-big5 ms950 | ||
+ | ibm-950_P110-1999 5 ★ibm-950_P110-1999 ibm-950 cp950 950 x-IBM950 | ||
+ | ibm-1375_P100-2008 5 ★ibm-1375_P100-2008 ibm-1375 Big5-HKSCS big5hk HKSCS-BIG5 | ||
+ | ibm-5471_P100-2006 7 ★ibm-5471_P100-2006 ibm-5471 Big5-HKSCS MS950_HKSCS hkbig5 big5-hkscs:unicode3.0 x-MS950-HKSCS | ||
+ | ibm-1386_P100-2001 5 ★ibm-1386_P100-2001 ibm-1386 cp1386 windows-936 ibm-1386_VSUB_VPUA | ||
+ | windows-936-2000 5 ★windows-936-2000 GBK CP936 MS936 windows-936 | ||
+ | ibm-1383_P110-1999 10 ★ibm-1383_P110-1999 ibm-1383 GB2312 csGB2312 cp1383 1383 EUC-CN ibm-eucCN hp15CN ibm-1383_VPUA | ||
+ | ibm-5478_P100-1995 8 ★ibm-5478_P100-1995 ibm-5478 GB_2312-80 chinese iso-ir-58 csISO58GB231280 gb2312-1980 GB2312.1980-0 | ||
+ | euc-tw-2014 2 ★euc-tw-2014 EUC-TW | ||
+ | ibm-964_P110-1999 8 ★ibm-964_P110-1999 ibm-964 ibm-eucTW cns11643 cp964 964 ibm-964_VPUA x-IBM964 | ||
+ | ibm-949_P110-1999 6 ★ibm-949_P110-1999 ibm-949 cp949 949 ibm-949_VASCII_VSUB_VPUA x-IBM949 | ||
+ | ibm-949_P11A-1999 6 ★ibm-949_P11A-1999 ibm-949 cp949c ibm-949_VSUB_VPUA x-IBM949C IBM-949C | ||
+ | ibm-970_P110_P110-2006_U2 13 ★ibm-970_P110_P110-2006_U2 ibm-970 EUC-KR KS_C_5601-1987 windows-51949 csEUCKR ibm-eucKR KSC_5601 5601 cp97070 ibm-970_VPUA x-IBM970 | ||
+ | ibm-971_P100-1995 4 ★ibm-971_P100-1995 ibm-971 ibm-971_VPUA x-IBM971 | ||
+ | ibm-1363_P11B-1998 14 ★ibm-1363_P11B-1998 ibm-1363 KS_C_5601-1987 KS_C_5601-1989 KSC_5601 csKSC56011987 korean iso-ir-149 cp1363 5601 kscindows-949 ibm-1363_VSUB_VPUA x-IBM1363C | ||
+ | ibm-1363_P110-1997 4 ★ibm-1363_P110-1997 ibm-1363 ibm-1363_VASCII_VSUB_VPUA x-IBM1363 | ||
+ | windows-949-2000 10 ★windows-949-2000 windows-949 KS_C_5601-1987 KS_C_5601-1989 KSC_5601 csKSC56011987 korean iso-ir-149 ms949 x-KSC5601 | ||
+ | windows-874-2000 5 ★windows-874-2000 TIS-620 windows-874 MS874 x-windows-874 | ||
+ | ibm-874_P100-1995 8 ★ibm-874_P100-1995 ibm-874 ibm-9066 cp874 TIS-620 tis620.2533 eucTH x-IBM874 | ||
+ | ibm-1162_P100-1999 2 ★ibm-1162_P100-1999 ibm-1162 | ||
+ | ibm-437_P100-1995 7 ★ibm-437_P100-1995 ibm-437 IBM437 cp437 437 csPC8CodePage437 windows-437 | ||
+ | ibm-720_P100-1997 5 ★ibm-720_P100-1997 ibm-720 windows-720 DOS-720 x-IBM720 | ||
+ | ibm-737_P100-1997 7 ★ibm-737_P100-1997 ibm-737 IBM737 cp737 windows-737 737 x-IBM737 | ||
+ | ibm-775_P100-1996 7 ★ibm-775_P100-1996 ibm-775 IBM775 cp775 csPC775Baltic windows-775 775 | ||
+ | ibm-850_P100-1995 7 ★ibm-850_P100-1995 ibm-850 IBM850 cp850 850 csPC850Multilingual windows-850 | ||
+ | ibm-851_P100-1995 6 ★ibm-851_P100-1995 ibm-851 IBM851 cp851 851 csPC851 | ||
+ | ibm-852_P100-1995 7 ★ibm-852_P100-1995 ibm-852 IBM852 cp852 852 csPCp852 windows-852 | ||
+ | ibm-855_P100-1995 8 ★ibm-855_P100-1995 ibm-855 IBM855 cp855 855 csIBM855 csPCp855 windows-855 | ||
+ | ibm-856_P100-1995 6 ★ibm-856_P100-1995 ibm-856 IBM856 cp856 856 x-IBM856 | ||
+ | ibm-857_P100-1995 7 ★ibm-857_P100-1995 ibm-857 IBM857 cp857 857 csIBM857 windows-857 | ||
+ | ibm-858_P100-1997 8 ★ibm-858_P100-1997 ibm-858 IBM00858 CCSID00858 CP00858 PC-Multilingual-850+euro cp858 windows-858 | ||
+ | ibm-860_P100-1995 6 ★ibm-860_P100-1995 ibm-860 IBM860 cp860 860 csIBM860 | ||
+ | ibm-861_P100-1995 8 ★ibm-861_P100-1995 ibm-861 IBM861 cp861 861 cp-is csIBM861 windows-861 | ||
+ | ibm-862_P100-1995 8 ★ibm-862_P100-1995 ibm-862 IBM862 cp862 862 csPC862LatinHebrew DOS-862 windows-862 | ||
+ | ibm-863_P100-1995 6 ★ibm-863_P100-1995 ibm-863 IBM863 cp863 863 csIBM863 | ||
+ | ibm-864_X110-1999 5 ★ibm-864_X110-1999 ibm-864 IBM864 cp864 csIBM864 | ||
+ | ibm-865_P100-1995 6 ★ibm-865_P100-1995 ibm-865 IBM865 cp865 865 csIBM865 | ||
+ | ibm-866_P100-1995 7 ★ibm-866_P100-1995 ibm-866 IBM866 cp866 866 csIBM866 windows-866 | ||
+ | ibm-867_P100-1998 3 ★ibm-867_P100-1998 ibm-867 x-IBM867 | ||
+ | ibm-868_P100-1995 7 ★ibm-868_P100-1995 ibm-868 IBM868 CP868 868 csIBM868 cp-ar | ||
+ | ibm-869_P100-1995 8 ★ibm-869_P100-1995 ibm-869 IBM869 cp869 869 cp-gr csIBM869 windows-869 | ||
+ | ibm-878_P100-1996 7 ★ibm-878_P100-1996 ibm-878 KOI8-R koi8 csKOI8R windows-20866 cp878 | ||
+ | ibm-901_P100-1999 2 ★ibm-901_P100-1999 ibm-901 | ||
+ | ibm-902_P100-1999 2 ★ibm-902_P100-1999 ibm-902 | ||
+ | ibm-922_P100-1999 6 ★ibm-922_P100-1999 ibm-922 IBM922 cp922 922 x-IBM922 | ||
+ | ibm-1168_P100-2002 4 ★ibm-1168_P100-2002 ibm-1168 KOI8-U windows-21866 | ||
+ | ibm-4909_P100-1999 2 ★ibm-4909_P100-1999 ibm-4909 | ||
+ | ibm-5346_P100-1998 4 ★ibm-5346_P100-1998 ibm-5346 windows-1250 cp1250 | ||
+ | ibm-5347_P100-1998 5 ★ibm-5347_P100-1998 ibm-5347 windows-1251 cp1251 ANSI1251 | ||
+ | ibm-5348_P100-1997 4 ★ibm-5348_P100-1997 ibm-5348 windows-1252 cp1252 | ||
+ | ibm-5349_P100-1998 4 ★ibm-5349_P100-1998 ibm-5349 windows-1253 cp1253 | ||
+ | ibm-5350_P100-1998 4 ★ibm-5350_P100-1998 ibm-5350 windows-1254 cp1254 | ||
+ | ibm-9447_P100-2002 4 ★ibm-9447_P100-2002 ibm-9447 windows-1255 cp1255 | ||
+ | ibm-9448_X100-2005 5 ★ibm-9448_X100-2005 ibm-9448 windows-1256 cp1256 x-windows-1256S | ||
+ | ibm-9449_P100-2002 4 ★ibm-9449_P100-2002 ibm-9449 windows-1257 cp1257 | ||
+ | ibm-5354_P100-1998 4 ★ibm-5354_P100-1998 ibm-5354 windows-1258 cp1258 | ||
+ | ibm-1250_P100-1995 3 ★ibm-1250_P100-1995 ibm-1250 windows-1250 | ||
+ | ibm-1251_P100-1995 3 ★ibm-1251_P100-1995 ibm-1251 windows-1251 | ||
+ | ibm-1252_P100-2000 3 ★ibm-1252_P100-2000 ibm-1252 windows-1252 | ||
+ | ibm-1253_P100-1995 3 ★ibm-1253_P100-1995 ibm-1253 windows-1253 | ||
+ | ibm-1254_P100-1995 3 ★ibm-1254_P100-1995 ibm-1254 windows-1254 | ||
+ | ibm-1255_P100-1995 2 ★ibm-1255_P100-1995 ibm-1255 | ||
+ | ibm-5351_P100-1998 3 ★ibm-5351_P100-1998 ibm-5351 windows-1255 | ||
+ | ibm-1256_P110-1997 2 ★ibm-1256_P110-1997 ibm-1256 | ||
+ | ibm-5352_P100-1998 3 ★ibm-5352_P100-1998 ibm-5352 windows-1256 | ||
+ | ibm-1257_P100-1995 2 ★ibm-1257_P100-1995 ibm-1257 | ||
+ | ibm-5353_P100-1998 3 ★ibm-5353_P100-1998 ibm-5353 windows-1257 | ||
+ | ibm-1258_P100-1997 3 ★ibm-1258_P100-1997 ibm-1258 windows-1258 | ||
+ | macos-0_2-10.2 7 ★macos-0_2-10.2 macintosh mac csMacintosh windows-10000 macroman x-macroman | ||
+ | macos-6_2-10.4 5 ★macos-6_2-10.4 x-mac-greek windows-10006 macgr x-MacGreek | ||
+ | macos-7_3-10.2 7 ★macos-7_3-10.2 x-mac-cyrillic windows-10007 mac-cyrillic maccy x-MacCyrillic x-MacUkraine | ||
+ | macos-29-10.2 7 ★macos-29-10.2 x-mac-centraleurroman windows-10029 x-mac-ce macce maccentraleurope x-MacCentralEurope | ||
+ | macos-35-10.2 5 ★macos-35-10.2 x-mac-turkish windows-10081 mactr x-MacTurkish | ||
+ | ibm-1051_P100-1995 7 ★ibm-1051_P100-1995 ibm-1051 hp-roman8 roman8 r8 csHPRoman8 x-roman8 | ||
+ | ibm-1276_P100-1995 4 ★ibm-1276_P100-1995 ibm-1276 Adobe-Standard-Encoding csAdobeStandardEncoding | ||
+ | ibm-1006_P100-1995 6 ★ibm-1006_P100-1995 ibm-1006 IBM1006 cp1006 1006 x-IBM1006 | ||
+ | ibm-1098_P100-1995 6 ★ibm-1098_P100-1995 ibm-1098 IBM1098 cp1098 1098 x-IBM1098 | ||
+ | ibm-1124_P100-1996 5 ★ibm-1124_P100-1996 ibm-1124 cp1124 1124 x-IBM1124 | ||
+ | ibm-1125_P100-1997 3 ★ibm-1125_P100-1997 ibm-1125 cp1125 | ||
+ | ibm-1129_P100-1997 2 ★ibm-1129_P100-1997 ibm-1129 | ||
+ | ibm-1131_P100-1997 3 ★ibm-1131_P100-1997 ibm-1131 cp1131 | ||
+ | ibm-1133_P100-1997 2 ★ibm-1133_P100-1997 ibm-1133 | ||
+ | ISO_2022,locale=ja,version=0 5 ★ISO_2022,locale=ja,version=0 ISO-2022-JP csISO2022JP x-windows-iso2022jp x-windows-50220 | ||
+ | ISO_2022,locale=ja,version=1 7 ★ISO_2022,locale=ja,version=1 ISO-2022-JP-1 JIS_Encoding csJISEncoding ibm-5054 JIS x-windows-50221 | ||
+ | ISO_2022,locale=ja,version=2 3 ★ISO_2022,locale=ja,version=2 ISO-2022-JP-2 csISO2022JP2 | ||
+ | ISO_2022,locale=ja,version=3 2 ★ISO_2022,locale=ja,version=3 JIS7 | ||
+ | ISO_2022,locale=ja,version=4 2 ★ISO_2022,locale=ja,version=4 JIS8 | ||
+ | ISO_2022,locale=ko,version=0 3 ★ISO_2022,locale=ko,version=0 ISO-2022-KR csISO2022KR | ||
+ | ISO_2022,locale=ko,version=1 2 ★ISO_2022,locale=ko,version=1 ibm-25546 | ||
+ | ISO_2022,locale=zh,version=0 4 ★ISO_2022,locale=zh,version=0 ISO-2022-CN csISO2022CN x-ISO-2022-CN-GB | ||
+ | ISO_2022,locale=zh,version=1 2 ★ISO_2022,locale=zh,version=1 ISO-2022-CN-EXT | ||
+ | ISO_2022,locale=zh,version=2 3 ★ISO_2022,locale=zh,version=2 ISO-2022-CN-CNS x-ISO-2022-CN-CNS | ||
+ | HZ 2 ★HZ HZ-GB-2312 | ||
+ | x11-compound-text 3 ★x11-compound-text COMPOUND_TEXT x-compound-text | ||
+ | ISCII,version=0 6 ★ISCII,version=0 x-ISCII91 x-iscii-de windows-57002 iscii-dev ibm-4902 | ||
+ | ISCII,version=1 6 ★ISCII,version=1 x-iscii-be windows-57003 iscii-bng windows-57006 x-iscii-as | ||
+ | ISCII,version=2 4 ★ISCII,version=2 x-iscii-pa windows-57011 iscii-gur | ||
+ | ISCII,version=3 4 ★ISCII,version=3 x-iscii-gu windows-57010 iscii-guj | ||
+ | ISCII,version=4 4 ★ISCII,version=4 x-iscii-or windows-57007 iscii-ori | ||
+ | ISCII,version=5 4 ★ISCII,version=5 x-iscii-ta windows-57004 iscii-tml | ||
+ | ISCII,version=6 4 ★ISCII,version=6 x-iscii-te windows-57005 iscii-tlg | ||
+ | ISCII,version=7 4 ★ISCII,version=7 x-iscii-ka windows-57008 iscii-knd | ||
+ | ISCII,version=8 4 ★ISCII,version=8 x-iscii-ma windows-57009 iscii-mlm | ||
+ | LMBCS-1 3 ★LMBCS-1 lmbcs ibm-65025 | ||
+ | ibm-37_P100-1995 13 ★ibm-37_P100-1995 ibm-37 IBM037 ibm-037 ebcdic-cp-us ebcdic-cp-ca ebcdic-cp-wt ebcdic-cp-nl csIBM037 cp037 037 cpibm3cp37 | ||
+ | ibm-273_P100-1995 7 ★ibm-273_P100-1995 ibm-273 IBM273 CP273 csIBM273 ebcdic-de 273 | ||
+ | ibm-277_P100-1995 9 ★ibm-277_P100-1995 ibm-277 IBM277 cp277 EBCDIC-CP-DK EBCDIC-CP-NO csIBM277 ebcdic-dk 277 | ||
+ | ibm-278_P100-1995 9 ★ibm-278_P100-1995 ibm-278 IBM278 cp278 ebcdic-cp-fi ebcdic-cp-se csIBM278 ebcdic-sv 278 | ||
+ | ibm-280_P100-1995 7 ★ibm-280_P100-1995 ibm-280 IBM280 CP280 ebcdic-cp-it csIBM280 280 | ||
+ | ibm-284_P100-1995 8 ★ibm-284_P100-1995 ibm-284 IBM284 CP284 ebcdic-cp-es csIBM284 cpibm284 284 | ||
+ | ibm-285_P100-1995 9 ★ibm-285_P100-1995 ibm-285 IBM285 CP285 ebcdic-cp-gb csIBM285 cpibm285 ebcdic-gb 285 | ||
+ | ibm-290_P100-1995 6 ★ibm-290_P100-1995 ibm-290 IBM290 cp290 EBCDIC-JP-kana csIBM290 | ||
+ | ibm-297_P100-1995 8 ★ibm-297_P100-1995 ibm-297 IBM297 cp297 ebcdic-cp-fr csIBM297 cpibm297 297 | ||
+ | ibm-420_X120-1999 7 ★ibm-420_X120-1999 ibm-420 IBM420 cp420 ebcdic-cp-ar1 csIBM420 420 | ||
+ | ibm-424_P100-1995 7 ★ibm-424_P100-1995 ibm-424 IBM424 cp424 ebcdic-cp-he csIBM424 424 | ||
+ | ibm-500_P100-1995 8 ★ibm-500_P100-1995 ibm-500 IBM500 CP500 ebcdic-cp-be csIBM500 ebcdic-cp-ch 500 | ||
+ | ibm-803_P100-1999 3 ★ibm-803_P100-1999 ibm-803 cp803 | ||
+ | ibm-838_P100-1995 8 ★ibm-838_P100-1995 ibm-838 IBM838 IBM-Thai csIBMThai cp838 838 ibm-9030 | ||
+ | ibm-870_P100-1995 7 ★ibm-870_P100-1995 ibm-870 IBM870 CP870 ebcdic-cp-roece ebcdic-cp-yu csIBM870 | ||
+ | ibm-871_P100-1995 8 ★ibm-871_P100-1995 ibm-871 IBM871 ebcdic-cp-is csIBM871 CP871 ebcdic-is 871 | ||
+ | ibm-875_P100-1995 6 ★ibm-875_P100-1995 ibm-875 IBM875 cp875 875 x-IBM875 | ||
+ | ibm-918_P100-1995 6 ★ibm-918_P100-1995 ibm-918 IBM918 CP918 ebcdic-cp-ar2 csIBM918 | ||
+ | ibm-930_P120-1999 8 ★ibm-930_P120-1999 ibm-930 ibm-5026 IBM930 cp930 930 x-IBM930 x-IBM930A | ||
+ | ibm-933_P110-1995 5 ★ibm-933_P110-1995 ibm-933 cp933 933 x-IBM933 | ||
+ | ibm-935_P110-1999 5 ★ibm-935_P110-1999 ibm-935 cp935 935 x-IBM935 | ||
+ | ibm-937_P110-1999 5 ★ibm-937_P110-1999 ibm-937 cp937 937 x-IBM937 | ||
+ | ibm-939_P120-1999 9 ★ibm-939_P120-1999 ibm-939 ibm-931 ibm-5035 IBM939 cp939 939 x-IBM939 x-IBM939A | ||
+ | ibm-1025_P100-1995 5 ★ibm-1025_P100-1995 ibm-1025 cp1025 1025 x-IBM1025 | ||
+ | ibm-1026_P100-1995 6 ★ibm-1026_P100-1995 ibm-1026 IBM1026 CP1026 csIBM1026 1026 | ||
+ | ibm-1047_P100-1995 5 ★ibm-1047_P100-1995 ibm-1047 IBM1047 cp1047 1047 | ||
+ | ibm-1097_P100-1995 5 ★ibm-1097_P100-1995 ibm-1097 cp1097 1097 x-IBM1097 | ||
+ | ibm-1112_P100-1995 5 ★ibm-1112_P100-1995 ibm-1112 cp1112 1112 x-IBM1112 | ||
+ | ibm-1122_P100-1999 5 ★ibm-1122_P100-1999 ibm-1122 cp1122 1122 x-IBM1122 | ||
+ | ibm-1123_P100-1995 5 ★ibm-1123_P100-1995 ibm-1123 cp1123 1123 x-IBM1123 | ||
+ | ibm-1130_P100-1997 2 ★ibm-1130_P100-1997 ibm-1130 | ||
+ | ibm-1132_P100-1998 2 ★ibm-1132_P100-1998 ibm-1132 | ||
+ | ibm-1137_P100-1999 2 ★ibm-1137_P100-1999 ibm-1137 | ||
+ | ibm-4517_P100-2005 2 ★ibm-4517_P100-2005 ibm-4517 | ||
+ | ibm-1140_P100-1997 7 ★ibm-1140_P100-1997 ibm-1140 IBM01140 CCSID01140 CP01140 cp1140 ebcdic-us-37+euro | ||
+ | ibm-1141_P100-1997 7 ★ibm-1141_P100-1997 ibm-1141 IBM01141 CCSID01141 CP01141 cp1141 ebcdic-de-273+euro | ||
+ | ibm-1142_P100-1997 8 ★ibm-1142_P100-1997 ibm-1142 IBM01142 CCSID01142 CP01142 cp1142 ebcdic-dk-277+euro ebcdic-no-277+euro | ||
+ | ibm-1143_P100-1997 8 ★ibm-1143_P100-1997 ibm-1143 IBM01143 CCSID01143 CP01143 cp1143 ebcdic-fi-278+euro ebcdic-se-278+euro | ||
+ | ibm-1144_P100-1997 7 ★ibm-1144_P100-1997 ibm-1144 IBM01144 CCSID01144 CP01144 cp1144 ebcdic-it-280+euro | ||
+ | ibm-1145_P100-1997 7 ★ibm-1145_P100-1997 ibm-1145 IBM01145 CCSID01145 CP01145 cp1145 ebcdic-es-284+euro | ||
+ | ibm-1146_P100-1997 7 ★ibm-1146_P100-1997 ibm-1146 IBM01146 CCSID01146 CP01146 cp1146 ebcdic-gb-285+euro | ||
+ | ibm-1147_P100-1997 7 ★ibm-1147_P100-1997 ibm-1147 IBM01147 CCSID01147 CP01147 cp1147 ebcdic-fr-297+euro | ||
+ | ibm-1148_P100-1997 7 ★ibm-1148_P100-1997 ibm-1148 IBM01148 CCSID01148 CP01148 cp1148 ebcdic-international-500+euro | ||
+ | ibm-1149_P100-1997 7 ★ibm-1149_P100-1997 ibm-1149 IBM01149 CCSID01149 CP01149 cp1149 ebcdic-is-871+euro | ||
+ | ibm-1153_P100-1999 4 ★ibm-1153_P100-1999 ibm-1153 IBM1153 x-IBM1153 | ||
+ | ibm-1154_P100-1999 2 ★ibm-1154_P100-1999 ibm-1154 | ||
+ | ibm-1155_P100-1999 2 ★ibm-1155_P100-1999 ibm-1155 | ||
+ | ibm-1156_P100-1999 2 ★ibm-1156_P100-1999 ibm-1156 | ||
+ | ibm-1157_P100-1999 2 ★ibm-1157_P100-1999 ibm-1157 | ||
+ | ibm-1158_P100-1999 2 ★ibm-1158_P100-1999 ibm-1158 | ||
+ | ibm-1160_P100-1999 2 ★ibm-1160_P100-1999 ibm-1160 | ||
+ | ibm-1164_P100-1999 2 ★ibm-1164_P100-1999 ibm-1164 | ||
+ | ibm-1364_P110-2007 3 ★ibm-1364_P110-2007 ibm-1364 x-IBM1364 | ||
+ | ibm-1371_P100-1999 3 ★ibm-1371_P100-1999 ibm-1371 x-IBM1371 | ||
+ | ibm-1388_P103-2001 4 ★ibm-1388_P103-2001 ibm-1388 ibm-9580 x-IBM1388 | ||
+ | ibm-1390_P110-2003 3 ★ibm-1390_P110-2003 ibm-1390 x-IBM1390 | ||
+ | ibm-1399_P110-2003 3 ★ibm-1399_P110-2003 ibm-1399 x-IBM1399 | ||
+ | ibm-5123_P100-1999 2 ★ibm-5123_P100-1999 ibm-5123 | ||
+ | ibm-8482_P100-1999 2 ★ibm-8482_P100-1999 ibm-8482 | ||
+ | ibm-16684_P110-2003 3 ★ibm-16684_P110-2003 ibm-16684 ibm-20780 | ||
+ | ibm-4899_P100-1998 2 ★ibm-4899_P100-1998 ibm-4899 | ||
+ | ibm-4971_P100-1999 2 ★ibm-4971_P100-1999 ibm-4971 | ||
+ | ibm-9067_X100-2005 2 ★ibm-9067_X100-2005 ibm-9067 | ||
+ | ibm-12712_P100-1998 3 ★ibm-12712_P100-1998 ibm-12712 ebcdic-he | ||
+ | ibm-16804_X110-1999 3 ★ibm-16804_X110-1999 ibm-16804 ebcdic-ar | ||
+ | ibm-37_P100-1995,swaplfnl 2 ★ibm-37_P100-1995,swaplfnl ibm-37-s390 | ||
+ | ibm-1047_P100-1995,swaplfnl 3 ★ibm-1047_P100-1995,swaplfnl ibm-1047-s390 IBM1047_LF | ||
+ | ibm-1140_P100-1997,swaplfnl 2 ★ibm-1140_P100-1997,swaplfnl ibm-1140-s390 | ||
+ | ibm-1141_P100-1997,swaplfnl 3 ★ibm-1141_P100-1997,swaplfnl ibm-1141-s390 IBM1141_LF | ||
+ | ibm-1142_P100-1997,swaplfnl 2 ★ibm-1142_P100-1997,swaplfnl ibm-1142-s390 | ||
+ | ibm-1143_P100-1997,swaplfnl 2 ★ibm-1143_P100-1997,swaplfnl ibm-1143-s390 | ||
+ | ibm-1144_P100-1997,swaplfnl 2 ★ibm-1144_P100-1997,swaplfnl ibm-1144-s390 | ||
+ | ibm-1145_P100-1997,swaplfnl 2 ★ibm-1145_P100-1997,swaplfnl ibm-1145-s390 | ||
+ | ibm-1146_P100-1997,swaplfnl 2 ★ibm-1146_P100-1997,swaplfnl ibm-1146-s390 | ||
+ | ibm-1147_P100-1997,swaplfnl 2 ★ibm-1147_P100-1997,swaplfnl ibm-1147-s390 | ||
+ | ibm-1148_P100-1997,swaplfnl 2 ★ibm-1148_P100-1997,swaplfnl ibm-1148-s390 | ||
+ | ibm-1149_P100-1997,swaplfnl 2 ★ibm-1149_P100-1997,swaplfnl ibm-1149-s390 | ||
+ | ibm-1153_P100-1999,swaplfnl 2 ★ibm-1153_P100-1999,swaplfnl ibm-1153-s390 | ||
+ | ibm-12712_P100-1998,swaplfnl 2 ★ibm-12712_P100-1998,swaplfnl ibm-12712-s390 | ||
+ | ibm-16804_X110-1999,swaplfnl 2 ★ibm-16804_X110-1999,swaplfnl ibm-16804-s390 | ||
+ | ebcdic-xml-us 1 ★ebcdic-xml-us | ||
+ | </syntaxhighlight2> | ||
+ | |||
+ | |||
+ | ICU4Cを使ったプログラムをリリースするときは必要なDLLも一緒にexeファイルと同じディレクトリに置いて配布する必要があります。Win32プロジェクトなら[ICU配置パス]\icu\bin\icuuc**.dllが必要になります。x64プロジェクトなら[ICU配置パス]\icu\bin64\icuuc**.dllが必要になります。プロジェクト設定によりbin or bin64\追加libファイル名+バージョン番号.dllという具合にライブラリと対になってると思っていいです。できれば配布する前に開発環境が導入されていない通常のPCで動作チェックするのがよいです。環境が準備できないなら誰かに人柱になってもらって、確認がとれてから正式リリースとか、そういう風にした方がよいです。自分は以前に配布するべきファイルセットを間違えて、迷惑をかけたことがありますので、チェックするようにしています。 | ||
+ | |||
=='''文字列大文字小文字変換'''== | =='''文字列大文字小文字変換'''== | ||
+ | これは、まぁ関数がありますので簡単に実現できます。 | ||
+ | aBcdEfgに書かれているものをABCDEFGに変換したり、あるいはabcdifgに変換したりできます。AbCDeFGみたいに入れ替えたり、英語の自然表記のため文章の始めの文字を探したり、略語や固有名詞の先頭文字を大文字にし、そのほかを小文字にするのはまた別の話になります。入れ替えくらいなら機械的な操作なのでやれると思います。大文字と小文字を同一視する必要のある検索の一致や大文字と小文字を区別しないメールアドレスやドメイン名の文字列変換に利用することもあります。この変換にも先述したICUを利用することができますが、この程度であれば標準関数を利用した方がよいです。DLLファイルを配ったり、プロジェクトにLibライブラリを読み込んだりINCLUDEファイルを設定したり、大きな実行ファイル群を要することになります。どうせ配布するならICUを使った方がよかったりする場合もありますので、ケースバイケースでしょうか? | ||
+ | |||
+ | |||
+ | とりあえずは、ICUの方の変換を記載しておきます。大文字、小文字変換の他に日本語ひらがなとカタカナとローマ字の相互変換についてもサンプルを示しました。ICUを使えば、簡単に変換してくれます。完璧ではなさそうなので、一括変換する場合は注意して使う必要はありそうです。 | ||
+ | <syntaxhighlight2 lang="cpp" line start="1"> | ||
+ | #pragma once | ||
+ | |||
+ | #include "stdafx.h" | ||
+ | #include <stdlib.h> | ||
+ | #include <string> //std::string型定義 | ||
+ | #include <mbstring.h> //mbs***関数 | ||
+ | #include <iostream> //cpp cout etc 一般入出力関数 | ||
+ | #include <locale> //Locale関数 | ||
+ | #include <tchar.h> //TCHAR型+_tcs***関数 | ||
+ | #include "atlstr.h" //CString,CStringA,CStringWおよびLPTSTR,LPWSTR,LPSTR,LPCTSTR,LPCWSTR,LPCSTRの定義プリプロセッサ | ||
+ | #include "atlbase.h" //同上 | ||
+ | #include "cstringt.h" //CStringTの定義プリプロセッサ | ||
+ | |||
+ | //_bstr_t型を利用するプリプロセッサ | ||
+ | #include "comutil.h" | ||
+ | #ifdef _DEBUG | ||
+ | #pragma comment(lib, "comsuppwd.lib") | ||
+ | #else | ||
+ | #pragma comment(lib, "comsuppw.lib") | ||
+ | #endif | ||
+ | //_bstr_t | ||
+ | |||
+ | //ICU ucnvプリプロセッサ | ||
+ | #include <unicode/ucnv.h> | ||
+ | #include <unicode/translit.h> | ||
+ | #ifdef _DEBUG | ||
+ | //#pragma comment(lib, "icudt.lib") | ||
+ | #pragma comment(lib, "icuind.lib")//ICU Transliterate関数を使うために必要なライブラリ 正規表現関数も | ||
+ | #pragma comment(lib, "icuucd.lib")//ICU ucnvを使うために必要なライブラリ | ||
+ | //#pragma comment(lib, "icuiod.lib") | ||
+ | #else | ||
+ | //#pragma comment(lib, "icudt.lib") | ||
+ | #pragma comment(lib, "icuind.lib") | ||
+ | #pragma comment(lib, "icuuc.lib") | ||
+ | //#pragma comment(lib, "icuio.lib") | ||
+ | #endif | ||
+ | |||
+ | |||
+ | using namespace std; | ||
+ | |||
+ | { | ||
+ | _tsetlocale(LC_ALL, _T("Japanese")); | ||
+ | |||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | // 全角 → 半角変換 | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | UErrorCode errorNum = U_ZERO_ERROR; | ||
+ | int nStrSize; | ||
+ | |||
+ | //変換元となる全角リテラル | ||
+ | std::wstring wstringResult = L"あいうえおアイウエオABCDE@;:*+/"; | ||
+ | UnicodeString str(wstringResult.c_str());//変換関数にはUnicodeString型を使うので初期値関数を使って初期化。strは変更可能な変数である必要がある。ココでconstは駄目。 | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | // 半角 → 全角変換 | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | str = L"あいうえおアイウエオABCDE@;:*+/"; | ||
+ | Transliterator *myTrans = myTrans->createInstance(L"Halfwidth-Fullwidth", UTRANS_FORWARD, errorNum); | ||
+ | myTrans->transliterate(str); | ||
+ | printf("★半角 → 全角変換\n"); | ||
+ | wprintf(L"%s:\n",str.getTerminatedBuffer()); | ||
+ | printf("\n"); | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | // 小文字 → 大文字変換 | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | str = L"AbcDefGhiJKlmloPQRsTUvWxYzabcDeFgHiJkLmNoPQRstuvwxyZ"; | ||
+ | //delete[] myTrans; | ||
+ | myTrans = myTrans->createInstance(L"lt-Upper", UTRANS_FORWARD, errorNum); | ||
+ | myTrans->transliterate(str); | ||
+ | printf("★小文字 → 大文字変換\n"); | ||
+ | wprintf(L"%s:\n",str.getTerminatedBuffer()); | ||
+ | printf("\n"); | ||
+ | |||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | // 大文字 → 小文字変換 | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | str = L"AbcDefGhiJKlmloPQRsTUvWxYzabcDeFgHiJkLmNoPQRstuvwxyZ"; | ||
+ | //delete[] myTrans; | ||
+ | myTrans = myTrans->createInstance(L"lt-Lower", UTRANS_FORWARD, errorNum); | ||
+ | myTrans->transliterate(str); | ||
+ | printf("★大文字 → 小文字変換\n"); | ||
+ | wprintf(L"%s:\n",str.getTerminatedBuffer()); | ||
+ | printf("\n"); | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | // カタカナ → ひらがな変換 | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | str = L"あいうえおアイウエオギャギュギョアイウエオABCDE@;:*+/"; | ||
+ | //delete[] myTrans; | ||
+ | printf("★カタカナ → ひらがな\n"); | ||
+ | wprintf(L"%s:\n",str.getTerminatedBuffer()); | ||
+ | myTrans = myTrans->createInstance(L"Katakana-Hiragana", UTRANS_FORWARD, errorNum); | ||
+ | myTrans->transliterate(str); | ||
+ | wprintf(L"%s:\n",str.getTerminatedBuffer()); | ||
+ | printf("\n"); | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | // ひらがな → カタカナ変換 | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | str = L"あいうえおぎゃぎゅぎょアイウエオギャギュギョアイウエオABCDE@;:*+/"; | ||
+ | //delete[] myTrans; | ||
+ | printf("★ひらがな → カタカナ\n"); | ||
+ | wprintf(L"%s:\n",str.getTerminatedBuffer()); | ||
+ | myTrans = myTrans->createInstance(L"Hiragana-Katakana", UTRANS_FORWARD, errorNum); | ||
+ | myTrans->transliterate(str); | ||
+ | wprintf(L"%s:\n",str.getTerminatedBuffer()); | ||
+ | printf("\n"); | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | // ひらがな → カタカナ→半角変換 | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | str = L"あいうえおぎゃぎゅぎょアイウエオギャギュギョアイウエオABCDE@;:*+/"; | ||
+ | //delete[] myTrans; | ||
+ | printf("★ひらがな → カタカナ→半角変換\n"); | ||
+ | wprintf(L"%s:\n",str.getTerminatedBuffer()); | ||
+ | myTrans = myTrans->createInstance(L"Hiragana-Katakana", UTRANS_FORWARD, errorNum); | ||
+ | myTrans->transliterate(str); | ||
+ | myTrans = myTrans->createInstance(L"Fullwidth-Halfwidth", UTRANS_FORWARD, errorNum); | ||
+ | myTrans->transliterate(str); | ||
+ | wprintf(L"%s:\n",str.getTerminatedBuffer()); | ||
+ | printf("\n"); | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | // ひらがな → ローマ字変換 | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | str = L"あいうえおぎゃぎゅぎょアイウエオギャギュギョアイウエオABCDE@;:*+/"; | ||
+ | //delete[] myTrans; | ||
+ | printf("★ひらがな → ローマ字変換\n"); | ||
+ | wprintf(L"%s:\n",str.getTerminatedBuffer()); | ||
+ | myTrans = myTrans->createInstance(L"Hiragana-Latin", UTRANS_FORWARD, errorNum); | ||
+ | myTrans->transliterate(str); | ||
+ | wprintf(L"%s:\n",str.getTerminatedBuffer()); | ||
+ | printf("\n"); | ||
+ | |||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | // カタカナ → ローマ字変換 | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | str = L"あいうえおアイウエオギャギュギョアイウエオABCDE@;:*+/"; | ||
+ | //delete[] myTrans; | ||
+ | printf("★カタカナ → ローマ字変換\n"); | ||
+ | wprintf(L"%s:\n",str.getTerminatedBuffer()); | ||
+ | myTrans = myTrans->createInstance(L"Katakana-Latin", UTRANS_FORWARD, errorNum); | ||
+ | myTrans->transliterate(str); | ||
+ | wprintf(L"%s:\n",str.getTerminatedBuffer()); | ||
+ | printf("\n"); | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | // ローマ字 → ひらがな変換 | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | str = L"aiueogyagyugyochachuchepyapyupyovuzazishikemeアイウエオギャギュギョアイウエオABCDE@;:*+/"; | ||
+ | //delete[] myTrans; | ||
+ | printf("★ローマ字 → ひらがな変換\n"); | ||
+ | wprintf(L"%s:\n",str.getTerminatedBuffer()); | ||
+ | myTrans = myTrans->createInstance(L"Latin-Hiragana", UTRANS_FORWARD, errorNum); | ||
+ | myTrans->transliterate(str); | ||
+ | wprintf(L"%s:\n",str.getTerminatedBuffer()); | ||
+ | printf("\n"); | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | // ローマ字 → カタカナ変換 | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | str = L"aiueogyagyugyochachuchepyapyupyovuzazishikemeアイウエオギャギュギョアイウエオABCDE@;:*+/"; | ||
+ | //delete[] myTrans; | ||
+ | printf("★ローマ字 → カタカナ変換\n"); | ||
+ | wprintf(L"%s:\n",str.getTerminatedBuffer()); | ||
+ | myTrans = myTrans->createInstance(L"Latin-Katakana", UTRANS_FORWARD, errorNum); | ||
+ | myTrans->transliterate(str); | ||
+ | wprintf(L"%s:\n",str.getTerminatedBuffer()); | ||
+ | printf("\n"); | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | // ローマ字 → カタカナ→半角変換 | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | str = L"aiueogyagyugyochachuchepyapyupyovuzazishikemeアイウエオギャギュギョアイウエオABCDE@;:*+/"; | ||
+ | //delete[] myTrans; | ||
+ | printf("★ローマ字 → カタカナ→半角変換\n"); | ||
+ | wprintf(L"%s:\n",str.getTerminatedBuffer()); | ||
+ | myTrans = myTrans->createInstance(L"Latin-Katakana", UTRANS_FORWARD, errorNum); | ||
+ | myTrans->transliterate(str); | ||
+ | myTrans = myTrans->createInstance(L"Fullwidth-Halfwidth", UTRANS_FORWARD, errorNum); | ||
+ | myTrans->transliterate(str); | ||
+ | wprintf(L"%s:\n",str.getTerminatedBuffer()); | ||
+ | printf("\n"); | ||
+ | |||
+ | } | ||
+ | |||
+ | </syntaxhighlight2> | ||
+ | |||
+ | 出力結果 | ||
+ | <syntaxhighlight2 lang="text"> | ||
+ | ★小文字 → 大文字変換 | ||
+ | ABCDEFGHIJKLMLOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ: | ||
+ | |||
+ | ★大文字 → 小文字変換 | ||
+ | abcdefghijklmlopqrstuvwxyzabcdefghijklmnopqrstuvwxyz: | ||
+ | |||
+ | ★カタカナ → ひらがな | ||
+ | あいうえおアイウエオギャギュギョアイウエオABCDE@;:*+/: | ||
+ | あいうえおあいうえおぎゃぎゅぎょあいうえおABCDE@;:*+/: | ||
+ | |||
+ | ★ひらがな → カタカナ | ||
+ | あいうえおぎゃぎゅぎょアイウエオギャギュギョアイウエオABCDE@;:*+/: | ||
+ | アイウエオギャギュギョアイウエオギャギュギョアイウエオABCDE@;:*+/: | ||
+ | |||
+ | ★ひらがな → カタカナ→半角変換 | ||
+ | あいうえおぎゃぎゅぎょアイウエオギャギュギョアイウエオABCDE@;:*+/: | ||
+ | アイウエオギャギュギョアイウエオギャギュギョアイウエオABCDE@;:*+/: | ||
+ | |||
+ | ★ひらがな → ローマ字変換 | ||
+ | あいうえおぎゃぎゅぎょアイウエオギャギュギョアイウエオABCDE@;:*+/: | ||
+ | aiueogyagyugyoアイウエオg~ャg~ュg~ョアイウエオABCDE@;:*+/: | ||
+ | |||
+ | ★カタカナ → ローマ字変換 | ||
+ | あいうえおアイウエオギャギュギョアイウエオABCDE@;:*+/: | ||
+ | あいうえおaiueogyagyugyoaiueoABCDE@;:*+/: | ||
+ | |||
+ | ★ひらがな → ひらがな変換 | ||
+ | aiueogyagyugyochachuchepyapyupyovuzazishikemeアイウエオギャギュギョアイウエオABCDE@;:*+/: | ||
+ | あいうえおぎゃぎゅぎょちゃちゅちぇぴゃぴゅぴょヴざぜぃしけめアイウエオギャギュギョアイウエオあぶくで@;:*+/: | ||
+ | |||
+ | ★ひらがな → カタカナ変換 | ||
+ | aiueogyagyugyochachuchepyapyupyovuzazishikemeアイウエオギャギュギョアイウエオABCDE@;:*+/: | ||
+ | アイウエオギャギュギョチャチュチェピャピュピョヴザゼィシケメアイウエオギャギュギョアイウエオアブクデ@;:*+/: | ||
+ | |||
+ | ★ひらがな → カタカナ→半角変換 | ||
+ | aiueogyagyugyochachuchepyapyupyovuzazishikemeアイウエオギャギュギョアイウエオABCDE@;:*+/: | ||
+ | アイウエオギャギュギョチャチュチェピャピュピョヴザゼィシケメアイウエオギャギュギョアイウエオアブクデ@;:*+/: | ||
+ | |||
+ | </syntaxhighlight2> | ||
+ | ひらがな→ローマ字変換が残念な結果になっているようでして、ひらがなと一緒に記述していたカタカナのギャギュギョをg~ャg~ュg~ョと変換してしまったようです。こんな変換をプログラムで提供することは稀れだと思いますが、ICUのバグのようですので、注意して使いましょう。ひらがなローマ字変換とか変換遊びの範囲まで来てるような気がします。やってみようとするところは凄いと思います。ほかにもたくさんの変換マップがあるようです。テキストエディタで特殊な変換を提供してみるのもおもしろいのかもしれません。使いこなせるユーザの方が少なさそうです。半角全角変換も同じような要領で実施できます。これらの変換は基本的にはUnicodeの中で実施され、その後、Unicodeから違う文字コードへの変換をするといった作業にで文字コードへの対応を実現します。次の項目では、これらの変換と同時に文字コードの変換を行う手法についても触れています。 | ||
+ | |||
+ | |||
+ | と、その前に、ICUを使わない大文字小文字変換もあるのでそのサンプルを記述します。利用する関数は | ||
+ | |||
+ | |||
+ | 大文字→小文字変換 | ||
+ | |||
+ | _strlwr、_wcslwr、_mbslwr、_strlwr_l、_wcslwr_l、_mbslwr_l | ||
+ | |||
+ | http://msdn.microsoft.com/ja-jp/library/vstudio/hkxwh33z.aspx | ||
+ | |||
+ | _strlwr_s、_strlwr_s_l、_mbslwr_s、_mbslwr_s_l、_wcslwr_s、_wcslwr_s_l | ||
+ | |||
+ | http://msdn.microsoft.com/ja-jp/library/vstudio/y889wzfw.aspx | ||
+ | |||
+ | <nowiki>***</nowiki>lwr***系の関数になります。例によって_str***に_wcs***、_mbs***と接尾句に****_sや****_lそして****_s_lがつくものの組み合わせが存在しています。 | ||
+ | |||
+ | |||
+ | 小文字→大文字変換 | ||
+ | |||
+ | _strupr、_strupr_l、_mbsupr、_mbsupr_l、_wcsupr_l、_wcsupr | ||
+ | |||
+ | http://msdn.microsoft.com/ja-jp/library/vstudio/sch3dy08.aspx | ||
+ | |||
+ | _strupr_s、_strupr_s_l、_mbsupr_s、_mbsupr_s_l、_wcsupr_s、_wcsupr_s_l | ||
+ | |||
+ | http://msdn.microsoft.com/ja-jp/library/vstudio/sae941fh.aspx | ||
+ | |||
+ | <nowiki>***</nowiki>upr***系の関数になります。こちらも_str***に_wcs***、_mbs***と接尾句に****_sや****_lそして****_s_lがつくものの組み合わせが存在しています。 | ||
+ | <syntaxhighlight2 lang="cpp" line start="1"> | ||
+ | #pragma once | ||
+ | #include "stdafx.h" | ||
+ | #include <stdlib.h> | ||
+ | #include <string> //std::string型定義 | ||
+ | #include <mbstring.h> //mbs***関数 | ||
+ | #include <iostream> //cpp cout etc 一般入出力関数 | ||
+ | #include <locale> //Locale関数 | ||
+ | #include <tchar.h> //TCHAR型+_tcs***関数 | ||
+ | #include "atlstr.h" //CString,CStringA,CStringWおよびLPTSTR,LPWSTR,LPSTR,LPCTSTR,LPCWSTR,LPCSTRの定義プリプロセッサ | ||
+ | #include "atlbase.h" //同上 | ||
+ | #include "cstringt.h" //CStringTの定義プリプロセッサ | ||
+ | #include <vector> | ||
+ | |||
+ | |||
+ | //_bstr_t型を利用するプリプロセッサ | ||
+ | #include "comutil.h" | ||
+ | #ifdef _DEBUG | ||
+ | #pragma comment(lib, "comsuppwd.lib") | ||
+ | #else | ||
+ | #pragma comment(lib, "comsuppw.lib") | ||
+ | #endif | ||
+ | //_bstr_t | ||
+ | |||
+ | //ICU ucnvプリプロセッサ | ||
+ | #include <unicode/ucnv.h> | ||
+ | #include <unicode/translit.h> | ||
+ | #include <unicode/regex.h> | ||
+ | #ifdef _DEBUG | ||
+ | //#pragma comment(lib, "icudt.lib") | ||
+ | #pragma comment(lib, "icuind.lib")//ICU Transliterate関数を使うために必要なライブラリ 正規表現関数も | ||
+ | #pragma comment(lib, "icuucd.lib")//ICU ucnvを使うために必要なライブラリ | ||
+ | //#pragma comment(lib, "icuiod.lib") | ||
+ | #else | ||
+ | #pragma comment(lib, "icudt.lib") | ||
+ | #pragma comment(lib, "icuind.lib") | ||
+ | #pragma comment(lib, "icuuc.lib") | ||
+ | #pragma comment(lib, "icuio.lib") | ||
+ | #endif | ||
+ | |||
+ | |||
+ | #include "UnicodeConverter.h" | ||
+ | |||
+ | |||
+ | using namespace std; | ||
+ | int _tmain(int argc, _TCHAR* argv[]) | ||
+ | { | ||
+ | int nSizeValue; | ||
+ | |||
+ | _wsetlocale( LC_ALL, L"Japanese"); | ||
+ | const char *ppcStr[]={"abCdefG","HijKLmn","OpQRSTu","vWxyZ"}; | ||
+ | |||
+ | nSizeValue = sizeof(ppcStr)/sizeof(*ppcStr); | ||
+ | |||
+ | char** ppcStrConv = new char*[nSizeValue]; | ||
+ | |||
+ | printf("★大文字→小文字変換\n"); | ||
+ | for(int i = 0; i < nSizeValue; i++){ | ||
+ | *(ppcStrConv + i) = new char[strlen(*(ppcStr + i)) + 1]; | ||
+ | strcpy_s(*(ppcStrConv + i),strlen(*(ppcStr + i)) + 1, (*(ppcStr + i))); | ||
+ | _strlwr_s(*(ppcStrConv + i), strlen(*(ppcStrConv + i)) + 1); | ||
+ | } | ||
+ | |||
+ | for(int i = 0; i < nSizeValue; i++){ | ||
+ | printf("%s\n",*(ppcStrConv + i)); | ||
+ | } | ||
+ | |||
+ | for(int i = 0; i < nSizeValue; i++){ | ||
+ | delete[] *(ppcStrConv + i); | ||
+ | } | ||
+ | |||
+ | |||
+ | printf("★小文字→大文字変換\n"); | ||
+ | for(int i = 0; i < nSizeValue; i++){ | ||
+ | *(ppcStrConv + i) = new char[strlen(*(ppcStr + i)) + 1]; | ||
+ | strcpy_s(*(ppcStrConv + i),strlen(*(ppcStr + i)) + 1, (*(ppcStr + i))); | ||
+ | _strupr_s(*(ppcStrConv + i), strlen(*(ppcStrConv + i)) + 1); | ||
+ | } | ||
+ | |||
+ | for(int i = 0; i < nSizeValue; i++){ | ||
+ | printf("%s\n",*(ppcStrConv + i)); | ||
+ | } | ||
+ | |||
+ | for(int i = 0; i < nSizeValue; i++){ | ||
+ | delete[] *(ppcStrConv + i); | ||
+ | } | ||
+ | return 0; | ||
+ | } | ||
+ | </syntaxhighlight2> | ||
+ | 出力結果 | ||
+ | <syntaxhighlight2 lang="text"> | ||
+ | ★大文字→小文字変換 | ||
+ | abcdefg | ||
+ | hijklmn | ||
+ | opqrstu | ||
+ | vwxyz | ||
+ | ★小文字→大文字変換 | ||
+ | ABCDEFG | ||
+ | HIJKLMN | ||
+ | OPQRSTU | ||
+ | VWXYZ | ||
+ | </syntaxhighlight2> | ||
+ | 上記のように変換できます。余談になりますが、配列はppcStr[i]のように記述できますが、結局のところ *(ppcStr + i)のように書き直すことができます。配列を宣言したときに、その変数は既にポインタ変数になっているので、宣言したときから、配列変数であることを示すプレフィックス(接頭句)としてpをつけておくのもよいですね。ポインタの配列はppと接頭句が付けられますし、char型ならppcという具合の接頭句の規則を自分は使っています。intはiじゃなくてnを接頭句に使うんですけど。面倒になって接頭句を付け忘れたりもします。そうするとしばらくして、これ何の変数だっけ?という具合になるおじいちゃんぶりを発揮します。たぶん、こうなってくると、「さっき食べたでしょ?おじいちゃん(^_^)。」って言われると、もう断食状態になります。やばいです。人が書いたプログラムと合わせると、また接頭句の規則が乱れて、自分自身では理解ができなくなってくるのです。たぶん自分は大きなプログラムを作るのには向いていませんね。せめて個人的に作っているプログラムの範囲では、規則どおりにやって間違いを減らしたいと思います。チームでやるときは、今までにつちかってきた規則と基盤を胸にきざみつつも応用力が試されます。int nSize[] = {10,20,30};みたいに宣言したときも実はnSizeってのは、この配列の先頭アドレスを保有する変数になってるわけだから、int pnSize[] = {10,20,30};として宣言して、*(pnSize + i) みたいにして、使うのもいいし、pnSize[i]として配列のように使うのもいい。ポインタ変数をあつかってるんだなぁって意識できてるだけマシ。プロになると、まぁそんな細かい事いわなくても自然と意識できるんでしょう。ただ、構造体やらクラスの配列だとpSize[i].mValueとかpSize[i].mFunc()みたいにできるものでも *(pSize + i).xxxとはできず、(*(pSize + i)).mValue のように全体をカッコでくくらないと駄目です。そして、アロー演算子は(*(ポインタ変数)).mValueのようなメンバ変数や関数の参照をおきかえるものでしたから、配列を[]を使わないで表現できることをしっていれば、(pSize + i)->mValueと記述を切り替えるのもたやすいですね。 | ||
+ | |||
+ | <nowiki>***</nowiki>upr***や***lwr***関数のように与えられたポインタの実体を置き換える関数では、引数にconstやリテラルを与えることはできないのが常です。確保するメモリ領域を十分に考慮した実体化されたポインタ変数にコピーを作成して、それを引数にしなければなりません。関数によっては、実体の大きさを再定義して別のメモリ空間にさしかえてアドレスをポインタに格納して値を返却してくれます。こういった操作が多いので、動的にメモリを確保したりする手法を知っておくのは大事な知識となります。リテラルを使わないで変数宣言して十分な要素を確保してから、その変数のアドレスをポインタ変数に入れるという手法もありますが、文字数がどうなるかわからないプログラムでは、動的に確保するやり方をマスタしておかないと無駄にメモリを確保しなければならない場面が多くなってしまいます。配列や文字列を活用するには、動的なメモリ確保のやり方を把握しておいた方がいいですね。 | ||
+ | |||
=='''文字列半角文字全角文字変換'''== | =='''文字列半角文字全角文字変換'''== | ||
− | =='' | + | これは、標準関数では対応できませんが、ABCD…UVWXYZ@…abc…xyzをABCD…UVWXYZ@…abc…xyzに変換するような作業です。文字コードによっても求める結果や操作が違うので、ICUを使うのが手っ取り早いでしょう。自分で作成できる範囲の変換処理でもあります。 |
− | ==''' | + | |
− | ==''' | + | |
+ | 以下はICUを利用した全角→半角変換です。 | ||
+ | |||
+ | <syntaxhighlight2 lang="cpp" line start="1"> | ||
+ | #pragma once | ||
+ | |||
+ | #include "stdafx.h" | ||
+ | #include <stdlib.h> | ||
+ | #include <string> //std::string型定義 | ||
+ | #include <mbstring.h> //mbs***関数 | ||
+ | #include <iostream> //cpp cout etc 一般入出力関数 | ||
+ | #include <locale> //Locale関数 | ||
+ | #include <tchar.h> //TCHAR型+_tcs***関数 | ||
+ | #include "atlstr.h" //CString,CStringA,CStringWおよびLPTSTR,LPWSTR,LPSTR,LPCTSTR,LPCWSTR,LPCSTRの定義プリプロセッサ | ||
+ | #include "atlbase.h" //同上 | ||
+ | #include "cstringt.h" //CStringTの定義プリプロセッサ | ||
+ | |||
+ | //_bstr_t型を利用するプリプロセッサ | ||
+ | #include "comutil.h" | ||
+ | #ifdef _DEBUG | ||
+ | #pragma comment(lib, "comsuppwd.lib") | ||
+ | #else | ||
+ | #pragma comment(lib, "comsuppw.lib") | ||
+ | #endif | ||
+ | //_bstr_t | ||
+ | |||
+ | //ICU ucnvプリプロセッサ | ||
+ | #include <unicode/ucnv.h> | ||
+ | #include <unicode/translit.h> | ||
+ | #ifdef _DEBUG | ||
+ | //#pragma comment(lib, "icudt.lib") | ||
+ | #pragma comment(lib, "icuind.lib")//ICU Transliterate関数を使うために必要なライブラリ 正規表現関数も | ||
+ | #pragma comment(lib, "icuucd.lib")//ICU ucnvを使うために必要なライブラリ | ||
+ | //#pragma comment(lib, "icuiod.lib") | ||
+ | #else | ||
+ | #pragma comment(lib, "icudt.lib") | ||
+ | #pragma comment(lib, "icuind.lib") | ||
+ | #pragma comment(lib, "icuuc.lib") | ||
+ | #pragma comment(lib, "icuio.lib") | ||
+ | #endif | ||
+ | |||
+ | |||
+ | using namespace std; | ||
+ | int _tmain(int argc, _TCHAR* argv[]) | ||
+ | { | ||
+ | _tsetlocale(LC_ALL, _T("Japanese")); | ||
+ | |||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | // 全角 → 半角変換 | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | UConverter* ucnv; | ||
+ | UErrorCode errorNum = U_ZERO_ERROR; | ||
+ | int nStrSize; | ||
+ | |||
+ | //変換元となる全角リテラル | ||
+ | std::wstring wstringResult = L"あいうえおアイウエオABCDE@;:*+/"; | ||
+ | UnicodeString str(wstringResult.c_str());//変換関数にはUnicodeString型を使うので初期値関数を使って初期化。strは変更可能な変数である必要がある。ココでconstは駄目。 | ||
+ | |||
+ | //正しい変換結果確認用のリテラル | ||
+ | std::wstring wstringResult2 = L"あいうえおアイウエオABCDE@;:*+/"; | ||
+ | |||
+ | //変換処理の核となる部分 | ||
+ | //変換タイプリテラル | ||
+ | const UnicodeString convert_type(L"Fullwidth-Halfwidth"); | ||
+ | Transliterator *myTrans = myTrans->createInstance(convert_type, UTRANS_FORWARD, errorNum);//変換方法を設定 | ||
+ | myTrans->transliterate(str);//変換 | ||
+ | |||
+ | ucnv = ucnv_open("shift_jis", &errorNum); | ||
+ | std::string stringResult(str.length() * ucnv_getMaxCharSize(ucnv),'\0');//shift_jisの最大文字サイズと文字数で仮のメモリ確保 | ||
+ | ucnv_close(ucnv); | ||
+ | |||
+ | //UnicodeStringクラスを使った変換例。Unicode→任意の文字コード。 | ||
+ | //但しchar型へしか格納できない変数なのでUnicode→Unicodeのような無意味な変換には適さない。やれるけど… | ||
+ | nStrSize = str.extract(0, str.length(), &stringResult[0], "shift_jis");//stringResultにShift_JISに変換した内容を保管。 | ||
+ | stringResult.resize(nStrSize);//変換によって判明したメモリサイズに再設定 | ||
+ | |||
+ | |||
+ | //UnicodeStringのwchar_w型文字列を格納している先頭アドレスを取得できるメンバ関数。 | ||
+ | printf("★UnicodeString変数の出力サンプル\n"); | ||
+ | wprintf(L"%s:\n",str.getTerminatedBuffer()); | ||
+ | printf("\n"); | ||
+ | |||
+ | //★半角変換+shift_jis変換のバイトコード表示にためにchar型へ代入して出力 | ||
+ | printf("★半角変換+shift_jis変換\n"); | ||
+ | char* pcStr2 = new char[strlen(stringResult.c_str()) + 1]; | ||
+ | strcpy_s(pcStr2,strlen(stringResult.c_str()) + 1,stringResult.c_str()); | ||
+ | printf("%s %d:\n",stringResult.c_str(),strlen(stringResult.c_str()) + 1); | ||
+ | for(int i = 0;i < (int)strlen(stringResult.c_str()) + 1;i++){ | ||
+ | printf("%02x:",0x000000FF & *(pcStr2 + i)); | ||
+ | } | ||
+ | printf("\n"); | ||
+ | printf("\n"); | ||
+ | |||
+ | |||
+ | //★無変換のバイトコード表示にためにw_char型へ代入して出力 | ||
+ | printf("★全角無変換\n"); | ||
+ | wchar_t* pcStr = new wchar_t[wcslen(wstringResult.c_str()) + 1]; | ||
+ | wcscpy_s(pcStr,wcslen(wstringResult.c_str()) + 1,wstringResult.c_str()); | ||
+ | wprintf(L"%s %d:\n",wstringResult.c_str(),wcslen(wstringResult.c_str()) + 1); | ||
+ | for(int i = 0;i < (int)wcslen(wstringResult.c_str()) + 1;i++){ | ||
+ | printf("%02x:",0x0000FFFF & *(pcStr + i)); | ||
+ | } | ||
+ | printf("\n"); | ||
+ | printf("\n"); | ||
+ | |||
+ | |||
+ | //★変換後確認用の手動変換リテラルのバイトコード表示にためにw_char型へ代入して出力 | ||
+ | printf("★手動変換(確認用)\n"); | ||
+ | wchar_t* pcStr3 = new wchar_t[wcslen(wstringResult2.c_str()) + 1]; | ||
+ | wcscpy_s(pcStr3,wcslen(wstringResult2.c_str()) + 1,wstringResult2.c_str()); | ||
+ | wprintf(L"%s %d:\n",wstringResult2.c_str(),wcslen(wstringResult2.c_str()) + 1); | ||
+ | for(int i = 0;i < (int)wcslen(wstringResult2.c_str()) + 1;i++){ | ||
+ | printf("%02x:",0x0000FFFF & *(pcStr3 + i)); | ||
+ | } | ||
+ | printf("\n"); | ||
+ | printf("\n"); | ||
+ | |||
+ | //★変換処理をしたUnicodeのバイトコード表示にためにw_char型へ代入して出力 | ||
+ | printf("★半角変換Unicode版\n"); | ||
+ | wchar_t* pcStr4 = new wchar_t[wcslen(str.getTerminatedBuffer()) + 1]; | ||
+ | wcscpy_s(pcStr4,wcslen(str.getTerminatedBuffer()) + 1,str.getTerminatedBuffer()); | ||
+ | wprintf(L"%s %d:\n",str.getTerminatedBuffer(),wcslen(str.getTerminatedBuffer()) + 1); | ||
+ | for(int i = 0;i < (int)wcslen(str.getTerminatedBuffer()) + 1;i++){ | ||
+ | printf("%02x:",0x0000FFFF & *(pcStr4 + i)); | ||
+ | } | ||
+ | printf("\n"); | ||
+ | printf("\n"); | ||
+ | |||
+ | retuen 0; | ||
+ | } | ||
+ | </syntaxhighlight2> | ||
+ | 出力結果 | ||
+ | <syntaxhighlight2 lang="text"> | ||
+ | ★UnicodeString変数の出力サンプル | ||
+ | あいうえおアイウエオABCDE@;:*+/: | ||
+ | |||
+ | ★半角変換+shift_jis変換 | ||
+ | あいうえおアイウエオABCDE@;:*+/ 27: | ||
+ | 82:a0:82:a2:82:a4:82:a6:82:a8:b1:b2:b3:b4:b5:41:42:43:44:45:40:3b:3a:2a:2b:2f:00: | ||
+ | |||
+ | ★全角無変換 | ||
+ | あいうえおアイウエオABCDE@;:*+/ 22: | ||
+ | 3042:3044:3046:3048:304a:30a2:30a4:30a6:30a8:30aa:ff21:ff22:ff23:ff24:ff25:ff20:ff1b:ff1a:ff0a:ff0b:ff0f:0000: | ||
+ | |||
+ | ★手動変換(確認用) | ||
+ | あいうえおアイウエオABCDE@;:*+/ 22: | ||
+ | 3042:3044:3046:3048:304a:ff71:ff72:ff73:ff74:ff75:0041:0042:0043:0044:0045:0040:003b:003a:002a:002b:002f:0000: | ||
+ | |||
+ | ★半角変換Unicode版 | ||
+ | あいうえおアイウエオABCDE@;:*+/ 22: | ||
+ | 3042:3044:3046:3048:304a:ff71:ff72:ff73:ff74:ff75:0041:0042:0043:0044:0045:0040:003b:003a:002a:002b:002f:0000: | ||
+ | </syntaxhighlight2> | ||
+ | という感じに変換ができます。ICUの使い方さえわかれば、いろいろできますね。記事を書きながら、自分もようやくわかってきた感じ。ぉぃ。 | ||
+ | |||
+ | |||
+ | サンプルプログラムのコメントを読んでいただければ、理解できると思います。逆の変換はconverttypeを書き換えるだけです。 | ||
+ | |||
+ | |||
+ | createInstanceで指定できる変換タイプ名は以下のとおりです。 | ||
+ | <syntaxhighlight2 lang="text"> | ||
+ | Arabic-Latin | ||
+ | Arabic-Latin/BGN | ||
+ | Armenian-Latin | ||
+ | Armenian-Latin/BGN | ||
+ | Azerbaijani-Latin/BGN | ||
+ | Belarusian-Latin/BGN | ||
+ | Bengali-Devanagari | ||
+ | Bengali-Gujarati | ||
+ | Bengali-Gurmukhi | ||
+ | Bengali-Kannada | ||
+ | Bengali-Latin | ||
+ | Bengali-Malayalam | ||
+ | Bengali-Oriya | ||
+ | Bengali-Tamil | ||
+ | Bengali-Telugu | ||
+ | Bopomofo-Latin | ||
+ | Bulgarian-Latin/BGN | ||
+ | Cyrillic-Latin | ||
+ | Devanagari-Bengali | ||
+ | Devanagari-Gujarati | ||
+ | Devanagari-Gurmukhi | ||
+ | Devanagari-Kannada | ||
+ | Devanagari-Latin | ||
+ | Devanagari-Malayalam | ||
+ | Devanagari-Oriya | ||
+ | Devanagari-Tamil | ||
+ | Devanagari-Telugu | ||
+ | Digit-Tone | ||
+ | Fullwidth-Halfwidth | ||
+ | Georgian-Latin | ||
+ | Georgian-Latin/BGN | ||
+ | Greek-Latin | ||
+ | Greek-Latin/BGN | ||
+ | Greek-Latin/UNGEGN | ||
+ | Gujarati-Bengali | ||
+ | Gujarati-Devanagari | ||
+ | Gujarati-Gurmukhi | ||
+ | Gujarati-Kannada | ||
+ | Gujarati-Latin | ||
+ | Gujarati-Malayalam | ||
+ | Gujarati-Oriya | ||
+ | Gujarati-Tamil | ||
+ | Gujarati-Telugu | ||
+ | Gurmukhi-Bengali | ||
+ | Gurmukhi-Devanagari | ||
+ | Gurmukhi-Gujarati | ||
+ | Gurmukhi-Kannada | ||
+ | Gurmukhi-Latin | ||
+ | Gurmukhi-Malayalam | ||
+ | Gurmukhi-Oriya | ||
+ | Gurmukhi-Tamil | ||
+ | Gurmukhi-Telugu | ||
+ | Halfwidth-Fullwidth | ||
+ | Han-Latin | ||
+ | Han-Latin/Names | ||
+ | Hangul-Latin | ||
+ | Hans-Hant | ||
+ | Hant-Hans | ||
+ | Hebrew-Latin | ||
+ | Hebrew-Latin/BGN | ||
+ | Hiragana-Katakana | ||
+ | Hiragana-Latin | ||
+ | IPA-XSampa | ||
+ | Jamo-Latin | ||
+ | Kannada-Bengali | ||
+ | Kannada-Devanagari | ||
+ | Kannada-Gujarati | ||
+ | Kannada-Gurmukhi | ||
+ | Kannada-Latin | ||
+ | Kannada-Malayalam | ||
+ | Kannada-Oriya | ||
+ | Kannada-Tamil | ||
+ | Kannada-Telugu | ||
+ | Katakana-Hiragana | ||
+ | Katakana-Latin | ||
+ | Katakana-Latin/BGN | ||
+ | Kazakh-Latin/BGN | ||
+ | Kirghiz-Latin/BGN | ||
+ | Korean-Latin/BGN | ||
+ | Latin-ASCII | ||
+ | Latin-Arabic | ||
+ | Latin-Armenian | ||
+ | Latin-Bengali | ||
+ | Latin-Bopomofo | ||
+ | Latin-Cyrillic | ||
+ | Latin-Devanagari | ||
+ | Latin-Georgian | ||
+ | Latin-Greek | ||
+ | Latin-Greek/UNGEGN | ||
+ | Latin-Gujarati | ||
+ | Latin-Gurmukhi | ||
+ | Latin-Hangul | ||
+ | Latin-Hebrew | ||
+ | Latin-Hiragana | ||
+ | Latin-Jamo | ||
+ | Latin-Kannada | ||
+ | Latin-Katakana | ||
+ | Latin-Malayalam | ||
+ | Latin-NumericPinyin | ||
+ | Latin-Oriya | ||
+ | Latin-Syriac | ||
+ | Latin-Tamil | ||
+ | Latin-Telugu | ||
+ | Latin-Thaana | ||
+ | Latin-Thai | ||
+ | Macedonian-Latin/BGN | ||
+ | Malayalam-Bengali | ||
+ | Malayalam-Devanagari | ||
+ | Malayalam-Gujarati | ||
+ | Malayalam-Gurmukhi | ||
+ | Malayalam-Kannada | ||
+ | Malayalam-Latin | ||
+ | Malayalam-Oriya | ||
+ | Malayalam-Tamil | ||
+ | Malayalam-Telugu | ||
+ | Maldivian-Latin/BGN | ||
+ | Mongolian-Latin/BGN | ||
+ | NumericPinyin-Latin | ||
+ | NumericPinyin-Pinyin | ||
+ | Oriya-Bengali | ||
+ | Oriya-Devanagari | ||
+ | Oriya-Gujarati | ||
+ | Oriya-Gurmukhi | ||
+ | Oriya-Kannada | ||
+ | Oriya-Latin | ||
+ | Oriya-Malayalam | ||
+ | Oriya-Tamil | ||
+ | Oriya-Telugu | ||
+ | Pashto-Latin/BGN | ||
+ | Persian-Latin/BGN | ||
+ | Pinyin-NumericPinyin | ||
+ | Publishing-Any | ||
+ | Russian-Latin/BGN | ||
+ | Serbian-Latin/BGN | ||
+ | Simplified-Traditional | ||
+ | Syriac-Latin | ||
+ | Tamil-Bengali | ||
+ | Tamil-Devanagari | ||
+ | Tamil-Gujarati | ||
+ | Tamil-Gurmukhi | ||
+ | Tamil-Kannada | ||
+ | Tamil-Latin | ||
+ | Tamil-Malayalam | ||
+ | Tamil-Oriya | ||
+ | Tamil-Telugu | ||
+ | Telugu-Bengali | ||
+ | Telugu-Devanagari | ||
+ | Telugu-Gujarati | ||
+ | Telugu-Gurmukhi | ||
+ | Telugu-Kannada | ||
+ | Telugu-Latin | ||
+ | Telugu-Malayalam | ||
+ | Telugu-Oriya | ||
+ | Telugu-Tamil | ||
+ | Thaana-Latin | ||
+ | Thai-Latin | ||
+ | Tone-Digit | ||
+ | Traditional-Simplified | ||
+ | Turkmen-Latin/BGN | ||
+ | Ukrainian-Latin/BGN | ||
+ | Uzbek-Latin/BGN | ||
+ | XSampa-IPA | ||
+ | az-Lower | ||
+ | az-Title | ||
+ | az-Upper | ||
+ | ch-ch_FONIPA | ||
+ | cs-cs_FONIPA | ||
+ | cs-ja | ||
+ | cs-ko | ||
+ | cs_FONIPA-ja | ||
+ | cs_FONIPA-ko | ||
+ | dsb-dsb_FONIPA | ||
+ | el-Lower | ||
+ | el-Title | ||
+ | el-Upper | ||
+ | es-am | ||
+ | es-es_FONIPA | ||
+ | es-ja | ||
+ | es-zh | ||
+ | es_419-ja | ||
+ | es_419-zh | ||
+ | es_FONIPA-am | ||
+ | es_FONIPA-es_419_FONIPA | ||
+ | es_FONIPA-ja | ||
+ | es_FONIPA-zh | ||
+ | it-am | ||
+ | it-ja | ||
+ | ja_Latn-ko | ||
+ | ja_Latn-ru | ||
+ | la-la_FONIPA | ||
+ | lt-Lower | ||
+ | lt-Title | ||
+ | lt-Upper | ||
+ | nl-Title | ||
+ | pl-ja | ||
+ | pl-pl_FONIPA | ||
+ | pl_FONIPA-ja | ||
+ | ro-ja | ||
+ | ro-ro_FONIPA | ||
+ | ro_FONIPA-ja | ||
+ | ru-ja | ||
+ | ru-zh | ||
+ | sk-ja | ||
+ | sk-sk_FONIPA | ||
+ | sk_FONIPA-ja | ||
+ | tlh-tlh_FONIPA | ||
+ | tr-Lower | ||
+ | tr-Title | ||
+ | tr-Upper | ||
+ | uz_Cyrl-uz_Latn | ||
+ | uz_Latn-uz_Cyrl | ||
+ | yo-yo_BJ | ||
+ | zh_Latn_PINYIN-ru | ||
+ | Any-Null | ||
+ | Any-Lower | ||
+ | Any-Upper | ||
+ | Any-Title | ||
+ | Any-Name | ||
+ | Name-Any | ||
+ | Any-Remove | ||
+ | Any-Hex/Unicode | ||
+ | Any-Hex/Java | ||
+ | Any-Hex/C | ||
+ | Any-Hex/XML | ||
+ | Any-Hex/XML10 | ||
+ | Any-Hex/Perl | ||
+ | Any-Hex | ||
+ | Hex-Any/Unicode | ||
+ | Hex-Any/Java | ||
+ | Hex-Any/C | ||
+ | Hex-Any/XML | ||
+ | Hex-Any/XML10 | ||
+ | Hex-Any/Perl | ||
+ | Hex-Any | ||
+ | Any-NFC | ||
+ | Any-NFKC | ||
+ | Any-NFD | ||
+ | Any-NFKD | ||
+ | Any-FCD | ||
+ | Any-FCC | ||
+ | Any-ch_FONIPA | ||
+ | Any-Latin | ||
+ | Any-Telugu | ||
+ | Any-Gurmukhi | ||
+ | Any-Gujarati | ||
+ | Any-Malayalam | ||
+ | Any-Oriya | ||
+ | Any-Devanagari | ||
+ | Any-Kannada | ||
+ | Any-Tamil | ||
+ | Any-cs_FONIPA | ||
+ | Any-ru | ||
+ | Any-Bengali | ||
+ | Any-uz_Latn | ||
+ | Any-Katakana | ||
+ | Any-ro_FONIPA | ||
+ | Any-zh | ||
+ | Any-yo_BJ | ||
+ | Any-am | ||
+ | Any-es_419_FONIPA | ||
+ | Any-es_FONIPA | ||
+ | Any-sk_FONIPA | ||
+ | Any-Hant | ||
+ | Any-Hans | ||
+ | Any-Hiragana | ||
+ | Any-la_FONIPA | ||
+ | Any-dsb_FONIPA | ||
+ | Any-Syriac | ||
+ | Any-Greek | ||
+ | Any-Greek/UNGEGN | ||
+ | Any-Cyrillic | ||
+ | Any-Hangul | ||
+ | Any-Bopomofo | ||
+ | Any-Arabic | ||
+ | Any-Thai | ||
+ | Any-Armenian | ||
+ | Any-Thaana | ||
+ | Any-Georgian | ||
+ | Any-Hebrew | ||
+ | Any-uz_Cyrl | ||
+ | </syntaxhighlight2> | ||
+ | |||
+ | =='''文字列の検索と置換・正規表現'''== | ||
+ | 文字列の検索と置換は、メモ帳でCtrl+Fとかで検索するようなものや置換する処理と同じように目的の文字列を探す方法とファイルの検索のようにワイルドカードを使う方法があり、検索して一致した文字列を置き換えるという処理も同じみですが、もうひとつの検索と置換のやり方として、正規表現(Regular Expresion)という手法があります。これはワイルドカードによる指定にさらに文字列の先頭にある特定の文字列があって、さらに特定の文字列にはさまれた部分があって、文字列の最後尾にも特定の文字があったら、その挟まれた文字の先頭グループ1、グループ2、…グループnとして、順次、変換法則にしたがって変換といった複雑な指定が可能になる手法です。正規表現は複雑なこともできるし、単純なこともできる。できるだけ複雑なモノを単純にしてから操作をする手法など、検索と置換には多岐にわたる手法が存在します。また、検索効率をあげる手法もありかなり文字列操作の中でも奥深い技術を必要とする操作です。まずは単純な検索と置換。それと簡単な正規表現にチャレンジしてみましょう。正規表現の使い方をここでは取り上げて、正規表現による問題解決手法は、ここ以外での説明にしたいと思います。 | ||
+ | |||
+ | 以下、ICUのRegexを使った検索と置換の正規表現による処理のサンプルです。 | ||
+ | <syntaxhighlight2 lang="cpp" line start="1"> | ||
+ | #pragma once | ||
+ | |||
+ | #include "stdafx.h" | ||
+ | #include <stdlib.h> | ||
+ | #include <string> //std::string型定義 | ||
+ | #include <mbstring.h> //mbs***関数 | ||
+ | #include <iostream> //cpp cout etc 一般入出力関数 | ||
+ | #include <locale> //Locale関数 | ||
+ | #include <tchar.h> //TCHAR型+_tcs***関数 | ||
+ | #include "atlstr.h" //CString,CStringA,CStringWおよびLPTSTR,LPWSTR,LPSTR,LPCTSTR,LPCWSTR,LPCSTRの定義プリプロセッサ | ||
+ | #include "atlbase.h" //同上 | ||
+ | #include "cstringt.h" //CStringTの定義プリプロセッサ | ||
+ | #include <vector> | ||
+ | |||
+ | |||
+ | //_bstr_t型を利用するプリプロセッサ | ||
+ | #include "comutil.h" | ||
+ | #ifdef _DEBUG | ||
+ | #pragma comment(lib, "comsuppwd.lib") | ||
+ | #else | ||
+ | #pragma comment(lib, "comsuppw.lib") | ||
+ | #endif | ||
+ | //_bstr_t | ||
+ | |||
+ | //ICU ucnvプリプロセッサ | ||
+ | #include <unicode/ucnv.h> | ||
+ | #include <unicode/translit.h> | ||
+ | #include <unicode/regex.h> | ||
+ | #ifdef _DEBUG | ||
+ | //#pragma comment(lib, "icudt.lib") | ||
+ | #pragma comment(lib, "icuind.lib")//ICU Transliterate関数を使うために必要なライブラリ 正規表現関数も | ||
+ | #pragma comment(lib, "icuucd.lib")//ICU ucnvを使うために必要なライブラリ | ||
+ | //#pragma comment(lib, "icuiod.lib") | ||
+ | #else | ||
+ | #pragma comment(lib, "icudt.lib") | ||
+ | #pragma comment(lib, "icuind.lib") | ||
+ | #pragma comment(lib, "icuuc.lib") | ||
+ | #pragma comment(lib, "icuio.lib") | ||
+ | #endif | ||
+ | |||
+ | |||
+ | #include "UnicodeConverter.h" | ||
+ | |||
+ | |||
+ | using namespace std; | ||
+ | int _tmain(int argc, _TCHAR* argv[]) | ||
+ | { | ||
+ | |||
+ | _tsetlocale(LC_ALL, _T("Japanese")); | ||
+ | |||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | // 正規表現分割 | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | UParseError error; | ||
+ | UErrorCode status = U_ZERO_ERROR; | ||
+ | int nFindCnt = 0; | ||
+ | |||
+ | |||
+ | printf("★正規表現検索\n"); | ||
+ | UnicodeString regex = L"[,/とやも]";//正規表現検索文字 | ||
+ | RegexPattern* pattern = RegexPattern::compile(regex, error, status);//パターンを登録(コンパイル) | ||
+ | assert( U_SUCCESS(status) ); | ||
+ | |||
+ | UnicodeString input = L"リンゴとミカン/ナシとモモ,ごはんやおかず/おさけもつまみ,programと技術"; | ||
+ | assert( U_SUCCESS(status) ); | ||
+ | RegexMatcher* matcher = pattern->matcher(input, status);//入力値での正規表現検索処理をmatcherへ格納 | ||
+ | |||
+ | |||
+ | printf("★パターンマッチ結果出力\n"); | ||
+ | while ( matcher->find() ) { | ||
+ | //それぞれのマッチグループの出力。パターンに部分一致(.)が無い場合はつねにグループは1で要素0番のみ | ||
+ | for ( int32_t i = 0; i <= matcher->groupCount(); i++ ) { | ||
+ | std::wcout << L"[" << matcher->start(i,status) | ||
+ | << L"," << matcher->end(i,status) | ||
+ | << L"]" << matcher->group(i,status).getTerminatedBuffer() | ||
+ | << std::endl; | ||
+ | assert( U_SUCCESS(status) ); | ||
+ | } | ||
+ | //whileループ回数をカウントして分割数を記録 | ||
+ | nFindCnt++; | ||
+ | std::wcout << std::endl; | ||
+ | } | ||
+ | |||
+ | //分割した回数のUnicodeString変数の配列を確保して分割結果を配列に格納。 | ||
+ | printf("★検索された分割文字トークンの数\n"); | ||
+ | std::wcout << nFindCnt << std::endl; | ||
+ | printf("\n"); | ||
+ | |||
+ | UnicodeString* pfruits = new UnicodeString[nFindCnt + 1]; | ||
+ | int32_t splits = pattern->split(input, pfruits, nFindCnt + 1, status);//登録されたパターンで分割処理 | ||
+ | //splitの引数には入力文字列,要素が確保された出力文字列配列変数,分割数,実行結果 | ||
+ | |||
+ | assert( U_SUCCESS(status) ); | ||
+ | printf("★分割抽出した配列の出力\n"); | ||
+ | //分割によりそれぞれに格納された文字を文字列配列の全出力で確認 | ||
+ | for ( int32_t i = 0; i < splits; i++ ) { | ||
+ | std::wcout << pfruits[i].getTerminatedBuffer() << std::endl; | ||
+ | //std::wcout << (*(pfruits + i)).getTerminatedBuffer() << std::endl;こうやって表現しても同じ。 | ||
+ | } | ||
+ | printf("\n"); | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | // 正規表現置換 | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | UnicodeString replacement = L"+"; | ||
+ | |||
+ | |||
+ | /* | ||
+ | * 先頭置換 : replaceFirst | ||
+ | */ | ||
+ | printf("★先頭置換\n"); | ||
+ | UnicodeString result = matcher->replaceFirst(replacement, status); | ||
+ | assert( U_SUCCESS(status) ); | ||
+ | std::wcout << result.getTerminatedBuffer() << std::endl; | ||
+ | |||
+ | /* | ||
+ | * 一括置換 : replaceAll | ||
+ | */ | ||
+ | printf("★一括置換\n"); | ||
+ | result = matcher->replaceAll(replacement, status); | ||
+ | assert( U_SUCCESS(status) ); | ||
+ | std::wcout << result.getTerminatedBuffer() << std::endl; | ||
+ | |||
+ | /* | ||
+ | * 追記置換 : appendReplacement/appendAll 前方から逐次置換してresultに追加していく方式 | ||
+ | */ | ||
+ | printf("★追記置換\n"); | ||
+ | result = L""; | ||
+ | matcher->reset(); | ||
+ | while ( matcher->find() ) { | ||
+ | matcher->appendReplacement(result, replacement, status); | ||
+ | assert( U_SUCCESS(status) ); | ||
+ | //最後の置換完了状態で一時出力 | ||
+ | std::wcout << result.getTerminatedBuffer() << std::endl; | ||
+ | } | ||
+ | |||
+ | |||
+ | //最後の置換以降の残った文字列を追加 | ||
+ | matcher->appendTail(result); | ||
+ | std::wcout << result.getTerminatedBuffer() << std::endl; | ||
+ | |||
+ | printf("\n"); | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | // 部分一致 | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | /* | ||
+ | * 部分マッチ"(.)"の置換 | ||
+ | */ | ||
+ | regex = L"(.)([,/とやも]|$)";//正規表現検索文字 区切り文字or終端の一文字手前 $1を置換 区切り文字or終端は $2 | ||
+ | replacement = L"★";//伏字に置換 | ||
+ | result = input; | ||
+ | |||
+ | pattern = RegexPattern::compile(regex, error, status); | ||
+ | matcher = pattern->matcher(input, status); | ||
+ | |||
+ | |||
+ | printf("★パターンマッチ結果出力\n"); | ||
+ | while ( matcher->find() ) { | ||
+ | //それぞれのマッチグループの出力。パターンに部分一致(.)が無い場合はつねにグループは1で要素0番のみ | ||
+ | for ( int32_t i = 0; i <= matcher->groupCount(); i++ ) { | ||
+ | std::wcout << L"[" << matcher->start(i,status) | ||
+ | << L"," << matcher->end(i,status) | ||
+ | << L"]" << matcher->group(i,status).getTerminatedBuffer() | ||
+ | << std::endl; | ||
+ | assert( U_SUCCESS(status) ); | ||
+ | } | ||
+ | //whileループ回数をカウントして分割数を記録 | ||
+ | nFindCnt++; | ||
+ | std::wcout << std::endl; | ||
+ | } | ||
+ | |||
+ | |||
+ | typedef std::pair<int32_t,int32_t> range_type; | ||
+ | std::vector<range_type> matches; | ||
+ | |||
+ | |||
+ | matcher->reset(); | ||
+ | while ( matcher->find() ) { | ||
+ | // 第一グループを保存する 条件:$1 が存在して、検索の開始文字位置と終了文字位置が0以上なら保存 | ||
+ | if(matcher->groupCount() >= 1 && matcher->start(1,status) > 0 && matcher->end(1,status) > 0 ){ | ||
+ | matches.push_back(range_type(matcher->start(1,status), matcher->end(1,status))); | ||
+ | assert( U_SUCCESS(status) ); | ||
+ | } | ||
+ | } | ||
+ | // 末尾から置換 | ||
+ | while ( !matches.empty() ) { | ||
+ | range_type range = matches.back(); | ||
+ | matches.pop_back(); | ||
+ | result.replace(range.first, range.second - range.first, replacement); | ||
+ | } | ||
+ | printf("★部分一致パターンの置換結果出力\n"); | ||
+ | std::wcout << result.getTerminatedBuffer() << std::endl; | ||
+ | |||
+ | delete[] pfruits; | ||
+ | delete matcher; | ||
+ | delete pattern; | ||
+ | |||
+ | |||
+ | return 0; | ||
+ | } | ||
+ | </syntaxhighlight2> | ||
+ | 出力結果 | ||
+ | <syntaxhighlight2 lang="text"> | ||
+ | ★正規表現検索 | ||
+ | ★パターンマッチ結果出力 | ||
+ | [3,4]と | ||
+ | |||
+ | [7,8]/ | ||
+ | |||
+ | [10,11]と | ||
+ | |||
+ | [13,14], | ||
+ | |||
+ | [17,18]や | ||
+ | |||
+ | [21,22]/ | ||
+ | |||
+ | [25,26]も | ||
+ | |||
+ | [29,30], | ||
+ | |||
+ | [37,38]と | ||
+ | |||
+ | ★検索された分割文字トークンの数 | ||
+ | 9 | ||
+ | |||
+ | ★分割抽出した配列の出力 | ||
+ | リンゴ | ||
+ | ミカン | ||
+ | ナシ | ||
+ | モモ | ||
+ | ごはん | ||
+ | おかず | ||
+ | おさけ | ||
+ | つまみ | ||
+ | program | ||
+ | 技術 | ||
+ | |||
+ | ★先頭置換 | ||
+ | リンゴ+ミカン/ナシとモモ,ごはんやおかず/おさけもつまみ,programと技術 | ||
+ | ★一括置換 | ||
+ | リンゴ+ミカン+ナシ+モモ+ごはん+おかず+おさけ+つまみ+program+技術 | ||
+ | ★追記置換 | ||
+ | リンゴ+ | ||
+ | リンゴ+ミカン+ | ||
+ | リンゴ+ミカン+ナシ+ | ||
+ | リンゴ+ミカン+ナシ+モモ+ | ||
+ | リンゴ+ミカン+ナシ+モモ+ごはん+ | ||
+ | リンゴ+ミカン+ナシ+モモ+ごはん+おかず+ | ||
+ | リンゴ+ミカン+ナシ+モモ+ごはん+おかず+おさけ+ | ||
+ | リンゴ+ミカン+ナシ+モモ+ごはん+おかず+おさけ+つまみ+ | ||
+ | リンゴ+ミカン+ナシ+モモ+ごはん+おかず+おさけ+つまみ+program+ | ||
+ | リンゴ+ミカン+ナシ+モモ+ごはん+おかず+おさけ+つまみ+program+技術 | ||
+ | |||
+ | ★パターンマッチ結果出力 | ||
+ | [2,4]ゴと | ||
+ | [2,3]ゴ | ||
+ | [3,4]と | ||
+ | |||
+ | [6,8]ン/ | ||
+ | [6,7]ン | ||
+ | [7,8]/ | ||
+ | |||
+ | [9,11]シと | ||
+ | [9,10]シ | ||
+ | [10,11]と | ||
+ | |||
+ | [12,14]モ, | ||
+ | [12,13]モ | ||
+ | [13,14], | ||
+ | |||
+ | [16,18]んや | ||
+ | [16,17]ん | ||
+ | [17,18]や | ||
+ | |||
+ | [20,22]ず/ | ||
+ | [20,21]ず | ||
+ | [21,22]/ | ||
+ | |||
+ | [24,26]けも | ||
+ | [24,25]け | ||
+ | [25,26]も | ||
+ | |||
+ | [28,30]み, | ||
+ | [28,29]み | ||
+ | [29,30], | ||
+ | |||
+ | [36,38]mと | ||
+ | [36,37]m | ||
+ | [37,38]と | ||
+ | |||
+ | [39,40]術 | ||
+ | [39,40]術 | ||
+ | [40,40] | ||
+ | |||
+ | ★部分一致パターンの置換結果出力 | ||
+ | リン★とミカ★/ナ★とモ★,ごは★やおか★/おさ★もつま★,progra★と技★ | ||
+ | </syntaxhighlight2> | ||
+ | 149行目以降に記述した部分一致からのプログラムはやや複雑な表記になっていますが、これはICUに準備された関数だけでは部分一致の処理ができないために自分で工夫をしなければならないことに起因しています。 | ||
+ | |||
+ | |||
+ | 169行目のtypedef関数は宣言を置き換えるための命令文になります。std::pair<int32_t,int32_t>という構造体定義をrange_typeに置き換えるということを意味しています。 | ||
+ | またpairの後ろにある<int32_t,int32_t>というのはpairという構造体がテンプレート構造体として準備されていて、二つの型名を引数にとる必要がありここではint32_tという型を2つ指定して、pairというテンプレート構造体で使う2つの型はどちらもint型で使いますというテンプレート構造体の利用方法を記述している部分になります。pair構造体は2つの変数を対にして記憶するための構造体になっています。 | ||
+ | |||
+ | |||
+ | 170行目のvectorという関数もテンプレートクラスになっていて、要するにstd::vector< std::pair<int32_t,int32_t> >という宣言をしたのと同じことで、vectorクラスはstd::pair<int32_t,int32_t>という型で使いますという準備をした上でその変数として、matchesというものを使うという定義になります。vecotrは動的にメモリを確保するのを支援してくれるクラスで、push_backという関数の引数にstd::pair<int32_t,int32_t>(int型の数値,int型の数値)という構造体が持つコンストラクタによって返されるpair構造体型のポインタを記録しています。引数には検索した文字の開始位置と終了位置を入れています。vectorのbackという関数で最後に格納したポインタを返してくれるので、range_typeつまりstd::pair<int32_t,int32_t>型のrangeというポインタ変数にコピーしています。std::pairのメンバ変数firstにコンストラクタで使用した一つ目引数の数値が取得でき、メンバ変数secondで二つ目の引数の数値が取得できます。vecotorクラスのpop_back()という関数の呼び出しによって最後に格納したポインタを消すという処理をしてくれます。こうやってfind()で検索するすべての検索位置をvectorクラスの中にpair構造体でセットした2つのint型整数で検索された文字の開始位置と終了位置を記憶する仕組みです。テンプレートクラスやテンプレート構造体やクラスについて理解する必要があります。vectorのempty()関数は格納されたものが無くなったらtrueを返す関数で、while文のループ条件として!matches.empty()のようにして、空っぽではないあいだ繰り返すという処理になっています。 | ||
+ | |||
+ | |||
+ | 部分一致の処理は難しいので、typedef関数とクラスと構造体のコンストラクタとテンプレートクラスとクラスのメンバ関数およびクラスのメンバ変数、更には標準クラスであるvectorクラスとpair構造体について理解してから戻ってくるとよいかもしれません。 | ||
+ | |||
+ | |||
+ | ICUを使わない文字列検索としてはstrchrのような***chr系の一文字検索関数があります。見つかった位置のByte数を返してくれます。ICUの正規表現に比べると機能性は低いです。一文字を引数にするとき符号なし整数型にしなければいけないあたりは、初期値を与えての検索は楽ですが、実際に一文字の文字列から検索しようとすると大変なのかもしれません。実際に数えてみないと、一文字あたりが、1バイトなのか2バイトなのかわからないし…。こういう一文字検索だけを行う関数って使う人いるんだろか?って思う。やっぱstrstr系使うよね。 | ||
+ | |||
+ | |||
+ | 以下のサンプルでは文字列の検索をするもので、以下の関数も使っています。 | ||
+ | _strinc、_wcsinc、_mbsinc、_mbsinc_l のようなポインタ変数を1文字を進める関数。文字列の先頭を示していたものが次の文字になります。大元の文字列のポインタ変数を操作すると先頭文字を見失うので、通常は、同じアドレスを指し示すポインタ変数を複製して、複製したポインタ変数で操作します。 | ||
+ | 詳細は、以下のアドレスのとおりです。 | ||
+ | |||
+ | http://msdn.microsoft.com/ja-jp/library/vstudio/ex0hs2ad.aspx | ||
+ | |||
+ | _strdec、_wcsdec、_mbsdec、_mbsdec_l 一文字戻るにはこのような関数があります。 | ||
+ | |||
+ | http://msdn.microsoft.com/ja-jp/library/vstudio/cf10bexy.aspx | ||
+ | |||
+ | |||
+ | そして、strchr、wcschr、_mbschr、_mbschr_l は以下のような関数があって、ここでは_mbschrのサンプルを作りました。 | ||
+ | |||
+ | http://msdn.microsoft.com/ja-jp/library/vstudio/b34ccac3.aspx | ||
+ | |||
+ | |||
+ | 後方から検索するものとしては、strrchr、wcsrchr、_mbsrchr、_mbsrchr_lがあり、ここでは_mbsrchrを使っています。 | ||
+ | |||
+ | http://msdn.microsoft.com/ja-jp/library/vstudio/ftw0heb9.aspx | ||
+ | |||
+ | |||
+ | 更に文字列中を文字列で検索するものとしては、strstr、wcsstr、_mbsstr、_mbsstr_lがあり、ここでは_mbsstrを使っています。 | ||
+ | |||
+ | http://msdn.microsoft.com/ja-jp/library/vstudio/z9da80kz.aspx | ||
+ | |||
+ | |||
+ | マルチバイト文字の1文字を数値として取得する関数として | ||
+ | |||
+ | _strnextc、_wcsnextc、_mbsnextc、_mbsnextc_lがあり、ここでは_mbsnetcを使いました。その下に関数を使わない場合の数値の取得方法についても処理を記述しました。1文字バイト構成を羅列したときの整数値に変換した数値を抜き出したいという特殊な用途に応える関数になっています。自分で計算するのは面倒な手続きが必要になりそうなことがサンプルからわかると思います。 | ||
+ | |||
+ | http://msdn.microsoft.com/ja-jp/library/vstudio/5zsfy4ab.aspx | ||
+ | |||
+ | <syntaxhighlight2 lang="cpp" line start="1"> | ||
+ | #pragma once | ||
+ | #include "stdafx.h" | ||
+ | #include <stdlib.h> | ||
+ | #include <string> //std::string型定義 | ||
+ | #include <mbstring.h> //mbs***関数 | ||
+ | #include <iostream> //cpp cout etc 一般入出力関数 | ||
+ | #include <locale> //Locale関数 | ||
+ | #include <tchar.h> //TCHAR型+_tcs***関数 | ||
+ | #include "atlstr.h" //CString,CStringA,CStringWおよびLPTSTR,LPWSTR,LPSTR,LPCTSTR,LPCWSTR,LPCSTRの定義プリプロセッサ | ||
+ | #include "atlbase.h" //同上 | ||
+ | #include "cstringt.h" //CStringTの定義プリプロセッサ | ||
+ | #include <vector> | ||
+ | |||
+ | |||
+ | //_bstr_t型を利用するプリプロセッサ | ||
+ | #include "comutil.h" | ||
+ | #ifdef _DEBUG | ||
+ | #pragma comment(lib, "comsuppwd.lib") | ||
+ | #else | ||
+ | #pragma comment(lib, "comsuppw.lib") | ||
+ | #endif | ||
+ | //_bstr_t | ||
+ | |||
+ | //ICU ucnvプリプロセッサ | ||
+ | #include <unicode/ucnv.h> | ||
+ | #include <unicode/translit.h> | ||
+ | #include <unicode/regex.h> | ||
+ | #ifdef _DEBUG | ||
+ | //#pragma comment(lib, "icudt.lib") | ||
+ | #pragma comment(lib, "icuind.lib")//ICU Transliterate関数を使うために必要なライブラリ 正規表現関数も | ||
+ | #pragma comment(lib, "icuucd.lib")//ICU ucnvを使うために必要なライブラリ | ||
+ | //#pragma comment(lib, "icuiod.lib") | ||
+ | #else | ||
+ | #pragma comment(lib, "icudt.lib") | ||
+ | #pragma comment(lib, "icuind.lib") | ||
+ | #pragma comment(lib, "icuuc.lib") | ||
+ | #pragma comment(lib, "icuio.lib") | ||
+ | #endif | ||
+ | |||
+ | |||
+ | #include "UnicodeConverter.h" | ||
+ | |||
+ | |||
+ | using namespace std; | ||
+ | |||
+ | int _tmain(int argc, _TCHAR* argv[]) | ||
+ | { | ||
+ | |||
+ | int SingleChr = 'r'; | ||
+ | unsigned int mbSingleString; | ||
+ | unsigned int mbSingleStringNextC; | ||
+ | unsigned int nKeta; | ||
+ | |||
+ | char pcSingleStr[] = "列"; | ||
+ | char pcStr[] = "文字列"; | ||
+ | |||
+ | char pcString[] = "日本語文字の検索用文字列です。The quick brown dog jumps over the lazy fox"; | ||
+ | char fmt1[] = " 1 2 3 4 5 6"; | ||
+ | char fmt2[] = "123456789012345678901234567890123456789012345678901234567890123456789"; | ||
+ | |||
+ | char *pcPos; | ||
+ | unsigned char *pucPos; | ||
+ | unsigned char *pucRusultPos; | ||
+ | |||
+ | int result; | ||
+ | int result2; | ||
+ | |||
+ | printf_s( "文字列検索:\n\n %s\n", pcString ); | ||
+ | printf_s( " %s\n %s\n\n", fmt1, fmt2 ); | ||
+ | |||
+ | |||
+ | |||
+ | //★マルチバイト対応1文字の文字列で検索。 | ||
+ | printf_s( "★マルチバイト対応検索\n"); | ||
+ | |||
+ | pucPos = (unsigned char*)pcSingleStr; | ||
+ | |||
+ | mbSingleStringNextC = _mbsnextc(pucPos); | ||
+ | printf_s( "MultiByteString検索文字 SigngleWord:%04x(%s)\n", mbSingleStringNextC, pcSingleStr); | ||
+ | |||
+ | pucPos = _mbsinc(pucPos);//一文字分ポインタを進める関数 | ||
+ | result = (int)(pucPos - (unsigned char*)pcSingleStr); | ||
+ | mbSingleString = 0; | ||
+ | nKeta = 1; | ||
+ | for(int n = 0; n < result; n++){ | ||
+ | mbSingleString = mbSingleString + (*(pucPos - (n + 1))) * (nKeta); | ||
+ | printf_s( "%02x \n", (*(pucPos - (n + 1)))); | ||
+ | nKeta = nKeta * 0x100; | ||
+ | } | ||
+ | |||
+ | //printf_s( "%02x%02x\n", *(pucPos - 2), *(pucPos - 1));このカタチをunsigned int の変数に変形したのが mbSingleString | ||
+ | //unsigned int mbstringString = 'の';とかでも検索できますが、strcpy関数とかでコピーしてきた一文字の文字列でサンプル | ||
+ | |||
+ | printf_s( "MultiByteString検索文字 SigngleWord:%04x(%s)\n", mbSingleString, pcSingleStr); | ||
+ | printf_s( "incriment:%d[Byte]\n\n",result); | ||
+ | |||
+ | pucRusultPos = _mbschr((unsigned char*)pcString, mbSingleString); | ||
+ | result2 = (int)(pucRusultPos - (unsigned char*)pcString + 1); | ||
+ | if ( pucRusultPos != NULL ) | ||
+ | printf_s( "検索結果: 最初の %04x(%s) が見つかった位置は %d[Byte]目\n", mbSingleString, pcSingleStr, result2 ); | ||
+ | else | ||
+ | printf_s( "検索結果: %s not found\n\n", pcSingleStr ); | ||
+ | |||
+ | |||
+ | //★シングルバイト文字検索。 | ||
+ | printf_s( "\n\n"); | ||
+ | printf_s( "★シングルバイト文字の初期値による検索\n"); | ||
+ | printf_s( "検索文字: %c\n", SingleChr ); | ||
+ | |||
+ | |||
+ | //前方検索 | ||
+ | pcPos = strchr( pcString, SingleChr ); | ||
+ | result = (int)(pcPos - pcString + 1); | ||
+ | if ( pcPos != NULL ) | ||
+ | printf_s( "検索結果: 最初の %c が見つかった位置は %d[Byte]目\n", SingleChr, result ); | ||
+ | else | ||
+ | printf_s( "検索結果: %c not found\n", SingleChr ); | ||
+ | |||
+ | |||
+ | //後方検索 | ||
+ | pcPos = strrchr( pcString, SingleChr ); | ||
+ | result = (int)(pcPos - pcString + 1); | ||
+ | if ( pcPos != NULL ) | ||
+ | printf_s( "検索結果: 最後に %c が見つかった位置は %d[Byte]目\n", SingleChr, result ); | ||
+ | else | ||
+ | printf_s( "検索結果:\t%c not found\n", SingleChr ); | ||
+ | |||
+ | |||
+ | //★文字列への文字列検索。 | ||
+ | printf_s( "\n\n"); | ||
+ | printf_s( "★文字列への文字列検索\n"); | ||
+ | printf_s( "検索文字: %s\n", pcStr ); | ||
+ | |||
+ | pucRusultPos = _mbsstr((unsigned char*)pcString, (unsigned char*)pcStr); | ||
+ | result2 = (int)(pucRusultPos - (unsigned char*)pcString + 1); | ||
+ | if ( pucRusultPos != NULL ) | ||
+ | printf_s( "検索結果: 最初の (%s) が見つかった位置は %d[Byte]目\n", pcStr, result2 ); | ||
+ | else | ||
+ | printf_s( "検索結果: %s not found\n\n", pcSingleStr ); | ||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | |||
+ | </syntaxhighlight2> | ||
+ | 出力結果 等幅フォントに設定したテキストエディタに張り付けると、もう少し見やすくなります。 | ||
+ | |||
+ | 文字列検索: | ||
+ | |||
+ | 日本語文字の検索用文字列です。The quick brown dog jumps over the lazy fox | ||
+ | 1 2 3 4 5 6 | ||
+ | 123456789012345678901234567890123456789012345678901234567890123456789 | ||
+ | |||
+ | ★マルチバイト対応検索 | ||
+ | MultiByteString検索文字 SigngleWord:97f1(列) | ||
+ | f1 | ||
+ | 97 | ||
+ | MultiByteString検索文字 SigngleWord:97f1(列) | ||
+ | incriment:2[Byte] | ||
+ | |||
+ | 検索結果: 最初の 97f1(列) が見つかった位置は 23[Byte]目 | ||
+ | |||
+ | |||
+ | ★シングルバイト文字の初期値による検索 | ||
+ | 検索文字: r | ||
+ | 検索結果: 最初の r が見つかった位置は 42[Byte]目 | ||
+ | 検索結果: 最後に r が見つかった位置は 60[Byte]目 | ||
+ | |||
+ | |||
+ | ★文字列への文字列検索 | ||
+ | 検索文字: 文字列 | ||
+ | 検索結果: 最初の (文字列) が見つかった位置は 19[Byte]目 | ||
+ | |||
+ | 文字列全体の一致による検索の関数はstrstr関数で、***str系の関数です。他にも文字セット検索なるものはあります。 | ||
+ | |||
=='''文字列ファイルへの入出力'''== | =='''文字列ファイルへの入出力'''== | ||
− | * | + | ここまで、やってきた手法で文字列をファイルに保存することをやってみます。文字列はかならずしもテキストファイルとして保管されるものではありません。DBに格納されるもの、バイナリファイルに格納されるもの、圧縮されるもの、様々です。ここでは一般的なテキストファイルとして保管し、簡単なテキストDBとしての操作について作業します。 |
− | * | + | |
− | * | + | |
− | * | + | まずは、テキストから文字列の読み込みのサンプルをぺたぺたとしたいのですが、一応、標準の関数でサポートされている範囲の文字コードはShiftJISとUTF-8とUTF-16でVisualStudio2005からfopenやwfopen関数が拡張されて、2番目の引数ファイルオープンモード文字列に ccs=UTF-8とかccs=UTF-16LEと記載することで、ファイルポインタをつかってのストリーム入力時fgetws関数でワイド文字(UNICODE)に変換してくれます。テキストは自分で作るといいのですが、自分は以下のような簡単なテキストを文字コード別に準備したので、参考にリンクを張っておきます。なんてことないテキストファイルなので、無価値なのものです。 |
− | *正規表現 | + | |
− | * | + | [[メディア:文字列操作サンプル用文字コード4種セット.lzh | 文字列操作サンプル用文字コード4種セット.lzh]] |
− | * | + | |
− | * | + | JISやEUCといったサポートされていない文字コードのテキストファイルの場合はバイナリモードでファイルを読み込む必要があり、1バイトづつ処理をして、文字列として変換したりすることで、文字列操作を行います。変換そのものは先に紹介した文字コード変換で対応することが可能ですので、とりこんだバイナリコードをどうやって変換関数のなかに収めるかというのが課題になると思います。その例はのちほど考えるとして、まずはオーソドックスなファイルの読み込みからやってみます。 |
− | * | + | |
− | * | + | <syntaxhighlight2 lang="cpp" line start="1"> |
− | * | + | #pragma once |
− | * | + | #include "stdafx.h" |
− | * | + | #include <stdlib.h> |
− | * | + | #include <string> //std::string型定義 |
+ | #include <mbstring.h> //mbs***関数 | ||
+ | #include <iostream> //cpp cout etc 一般入出力関数 | ||
+ | #include <locale> //Locale関数 | ||
+ | #include <tchar.h> //TCHAR型+_tcs***関数 | ||
+ | #include "atlstr.h" //CString,CStringA,CStringWおよびLPTSTR,LPWSTR,LPSTR,LPCTSTR,LPCWSTR,LPCSTRの定義プリプロセッサ | ||
+ | #include "atlbase.h" //同上 | ||
+ | #include "cstringt.h" //CStringTの定義プリプロセッサ | ||
+ | #include <vector> | ||
+ | |||
+ | #include <sys/timeb.h> //Timeb型構造体 | ||
+ | |||
+ | //_bstr_t型を利用するプリプロセッサ | ||
+ | #include "comutil.h" | ||
+ | #ifdef _DEBUG | ||
+ | #pragma comment(lib, "comsuppwd.lib") | ||
+ | #else | ||
+ | #pragma comment(lib, "comsuppw.lib") | ||
+ | #endif | ||
+ | //_bstr_t | ||
+ | |||
+ | //ICU ucnvプリプロセッサ | ||
+ | #include <unicode/ucnv.h> | ||
+ | #include <unicode/translit.h> | ||
+ | #include <unicode/regex.h> | ||
+ | #ifdef _DEBUG | ||
+ | //#pragma comment(lib, "icudt.lib") | ||
+ | #pragma comment(lib, "icuind.lib")//ICU Transliterate関数を使うために必要なライブラリ 正規表現関数も | ||
+ | #pragma comment(lib, "icuucd.lib")//ICU ucnvを使うために必要なライブラリ | ||
+ | //#pragma comment(lib, "icuiod.lib") | ||
+ | #else | ||
+ | #pragma comment(lib, "icudt.lib") | ||
+ | #pragma comment(lib, "icuind.lib") | ||
+ | #pragma comment(lib, "icuuc.lib") | ||
+ | #pragma comment(lib, "icuio.lib") | ||
+ | #endif | ||
+ | |||
+ | |||
+ | #include "UnicodeConverter.h" | ||
+ | |||
+ | |||
+ | using namespace std; | ||
+ | int _tmain(int argc, _TCHAR* argv[]) | ||
+ | { | ||
+ | _tsetlocale(LC_ALL, _T("Japanese")); //ロケールセットすると_l関数でロケール指定しなくても日本語が使われます。 | ||
+ | |||
+ | _locale_t localeJpanease; | ||
+ | localeJpanease = _create_locale(LC_ALL, "Japanese"); | ||
+ | |||
+ | FILE* pfileText; | ||
+ | errno_t errNo; | ||
+ | size_t* psizeRuturnValue = new size_t; | ||
+ | int nCloseCnt; | ||
+ | wchar_t pwcStrFilePathNewTexttoBinary[] = L"C:\\...\\...\\...\\new_test_t2b.txt";//...\\...\\...には正確なパスを指定。 | ||
+ | wchar_t pwcStrFilePathNewUTF16LE[] = L"C:\\...\\...\\...\\new_test_utf16b.txt"; | ||
+ | wchar_t pwcStrFilePathNewUTF8[] = L"C:\\...\\...\\...\\new_test_utf8b.txt"; | ||
+ | wchar_t pwcStrFilePathNewUTF8BOM[] = L"C:\\...\\...\\...\\new_test_utf8bomb.txt"; | ||
+ | wchar_t pwcStrFilePathShiftJIS[] = L"C:\\...\\...\\...\\test.txt"; | ||
+ | wchar_t pwcStrFilePathJIS[] = L"C:\\...\\...\\...\\test_jis.txt"; | ||
+ | wchar_t pwcStrFilePathEUC[] = L"C:\\...\\...\\...\\test_euc.txt"; | ||
+ | wchar_t pwcStrFilePathUtf8Bom[] = L"C:\\...\\...\\...\\test_utf8.txt"; | ||
+ | wchar_t pwcStrFilePathUtf8[] = L"C:\\...\\...\\...\\test_utf8N.txt"; | ||
+ | wchar_t pwcStrFilePathUtf16LE[] = L"C:\\...\\...\\...\\test_utf16LE.txt"; | ||
+ | |||
+ | wchar_t pwcStrGohan[] = L"ごはんを食べたよ。\r\n";//\r\n = CR LF = 0x0D 0x0A | ||
+ | char* pcStrStream; | ||
+ | wchar_t* pwcStrStream; | ||
+ | char* pcStrErr; | ||
+ | wchar_t* pwcStrErr; | ||
+ | |||
+ | pcStrStream = new char[1024]; | ||
+ | pwcStrStream = new wchar_t[1024]; | ||
+ | pcStrErr = new char[1024]; | ||
+ | pwcStrErr = new wchar_t[1024]; | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //★UTF8のBOM無しテキストの読み込み | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | //※読み込みバッファを1024文字にしているので、1024文字以上の行を一続きにさせたい場合は、工夫が必要。それは後で考えます。 | ||
+ | //※行ごとにバッファの文字数を動的に確保したい場合、 | ||
+ | // 一文字づつスキャンして改行コードが現れるところまでのバイト長を確保するという手法もありそう。 | ||
+ | |||
+ | fpos_t* fposPos = new fpos_t; | ||
+ | |||
+ | printf("★UTF8のBOM無しテキストの読み込み\n"); | ||
+ | errNo = _wfopen_s( &pfileText, pwcStrFilePathUtf8, L"r,ccs=UTF-8"); | ||
+ | printf("Error?->%d\n", errNo); | ||
+ | |||
+ | fgetpos(pfileText, fposPos); | ||
+ | printf("fpos-> %04d\n", *fposPos); //ファイルを開いた時点でのポジションの確認。BOM無しだと0文字目。 | ||
+ | |||
+ | //Unicodeサンプル文字 1行目 | ||
+ | printf("文字コードUTF-16->"); | ||
+ | for(int i=0; i < (int)wcslen(pwcStrGohan) + 1; i++){ | ||
+ | printf("%04x:",*(pwcStrGohan + i)); | ||
+ | } | ||
+ | printf("\n"); | ||
+ | |||
+ | printf("utf8N.txtテキストファイルの中身とその他の情報出力\n"); | ||
+ | while(!feof(pfileText)){ | ||
+ | |||
+ | pwcStrErr = fgetws(pwcStrStream,1024,pfileText);//最終行がEOFのみの場合に失敗して1行前の値が残ることに注意。 | ||
+ | //先頭からUTF-8→UTF16形式で文字列を取得する。 | ||
+ | wprintf(L"%s(%s)\n", pwcStrStream, pwcStrErr);//UTF-16のpwcStrStreamをSJIS(Locale設定)で書き出し。UTF-16のままだと文字化けする。 | ||
+ | |||
+ | printf("文字コードUTF-16->"); | ||
+ | for(int i=0 ;i < 20 ;i++){ //Unicodeに変換された文字コードを先頭20文字だけ出力。 | ||
+ | printf("%04x:",*(pwcStrStream + i)); | ||
+ | } | ||
+ | |||
+ | fgetpos(pfileText, fposPos); | ||
+ | printf("fpos-> %04d\n", *fposPos); | ||
+ | } | ||
+ | printf("[EOF]"); | ||
+ | printf("\n"); | ||
+ | |||
+ | nCloseCnt = fclose(pfileText); | ||
+ | printf("nCloseErr->%d\n", nCloseCnt); | ||
+ | |||
+ | nCloseCnt = _fcloseall(); | ||
+ | printf("nCloseCnt->%d\n", nCloseCnt); | ||
+ | printf("\n"); | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //★UTF8のBOM有りテキストの読み込み | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | printf("★UTF8のBOM有りテキストの読み込み\n"); | ||
+ | errNo = _wfopen_s( &pfileText, pwcStrFilePathUtf8Bom, L"r,ccs=UTF-8"); | ||
+ | printf("Error?->%d\n", errNo); | ||
+ | |||
+ | fgetpos(pfileText, fposPos); | ||
+ | printf("fpos-> %04d\n", *fposPos); //ファイルを開いた時点でのポジションの確認。BOM無しだと3(0からカウントなので実際は4byte目)。 | ||
+ | |||
+ | printf("utf8.txtテキストファイルの中身\n"); | ||
+ | while(!feof(pfileText)){ | ||
+ | |||
+ | pwcStrErr = fgetws(pwcStrStream,1024,pfileText);//最終行がEOFのみの場合に失敗して1行前の値が残ることに注意。 | ||
+ | //UTF-8(BOMはEF BB BFなので4バイト目)からUTF16形式で文字列を取得する。 | ||
+ | //※FE FFをUTF-8でエンコードするとEF BB BF | ||
+ | //※FE FF = 1111 1110 1111 1111 を | ||
+ | // 1111 11 10 11 11 1111 を | ||
+ | // 1110 (XXXX) 10(XX) (XX)(YY) 10(YY) (YYYY)と割り当て | ||
+ | //1110 1111 1011 1011 1011 1111 = EF BB BF | ||
+ | |||
+ | if(pwcStrErr != NULL ){ | ||
+ | wprintf(L"%s", pwcStrStream);//UTF-16LEのpwcStrStreamをSJIS(Locale設定)で書き出し。UTF-16LEのままだと文字化けする。 | ||
+ | } | ||
+ | } | ||
+ | printf("[EOF]"); | ||
+ | printf("\n"); | ||
+ | |||
+ | nCloseCnt = fclose(pfileText); | ||
+ | printf("nCloseErr->%d\n", nCloseCnt); | ||
+ | printf("\n"); | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //★UTF16のBOM有りテキストの読み込み | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | printf("★UTF16LEのBOM有りテキストの読み込み\n"); | ||
+ | errNo = _wfopen_s( &pfileText, pwcStrFilePathUtf16LE, L"r,ccs=UTF-16LE"); | ||
+ | printf("Error?->%d\n", errNo); | ||
+ | |||
+ | fgetpos(pfileText, fposPos); | ||
+ | printf("fpos-> %04d\n", *fposPos); //ファイルを開いた時点でのポジションの確認。BOM有りで2(0からカウントなので実際は3byte目)。 | ||
+ | |||
+ | printf("utf8.txtテキストファイルの中身\n"); | ||
+ | while(!feof(pfileText)){ | ||
+ | |||
+ | pwcStrErr = fgetws(pwcStrStream,1024,pfileText);//最終行がEOFのみの場合に失敗して1行前の値が残ることに注意。 | ||
+ | if(pwcStrErr != NULL ){ //UTF-16(BOMはFE FFなので3バイト目)からUTF16形式で文字列を取得する。 | ||
+ | wprintf(L"%s", pwcStrStream);//UTF-16のpwcStrStreamをSJIS(Locale設定)で書き出し。UTF-16のままだと文字化けする。 | ||
+ | } | ||
+ | } | ||
+ | printf("[EOF]"); | ||
+ | printf("\n"); | ||
+ | |||
+ | nCloseCnt = fclose(pfileText); | ||
+ | printf("nCloseErr->%d\n", nCloseCnt); | ||
+ | printf("\n"); | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //★ShiftJISテキストの読み込み | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | printf("★ShiftJISテキストの読み込み\n"); | ||
+ | errNo = _wfopen_s( &pfileText, pwcStrFilePathShiftJIS, L"r"); | ||
+ | printf("Error?->%d\n", errNo); | ||
+ | |||
+ | fgetpos(pfileText, fposPos); | ||
+ | printf("fpos-> %04d\n", *fposPos); //ファイルを開いた時点でのポジションの確認。 | ||
+ | |||
+ | printf("test.txtテキストファイルの中身\n"); | ||
+ | while(!feof(pfileText)){ | ||
+ | |||
+ | pcStrErr = fgets(pcStrStream, 1024, pfileText);//最終行がEOFのみの場合に失敗して1行前の値が残ることに注意。 | ||
+ | if(pcStrErr != NULL ){ | ||
+ | printf("%s", pcStrStream); | ||
+ | } | ||
+ | } | ||
+ | printf("[EOF]"); | ||
+ | printf("\n"); | ||
+ | |||
+ | nCloseCnt = fclose(pfileText); | ||
+ | printf("nCloseErr->%d\n", nCloseCnt); | ||
+ | printf("\n"); | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //★JISテキストの読み込み | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | //int型でchar配列のサイズを動的に確保ができるので、int型の範囲のファイルなら | ||
+ | //一度に格納できるプログラムになっています。intの範囲を超えると動的メモリ確保で | ||
+ | //失敗します。その先の工夫はまた別途考える必要があります。少し筒変換したり…。 | ||
+ | |||
+ | int nSize = 0; | ||
+ | int nFeedCnt = 0; | ||
+ | |||
+ | char* pcStrFile; | ||
+ | fpos_t* pfposStartPos = new fpos_t; | ||
+ | printf("★JISテキストの読み込み\n"); | ||
+ | errNo = _wfopen_s( &pfileText, pwcStrFilePathJIS, L"rb"); | ||
+ | printf("Error?->%d\n", errNo); | ||
+ | |||
+ | fgetpos(pfileText, fposPos); | ||
+ | printf("fpos-> %04d\n", *fposPos); //ファイルを開いた時点でのポジションの確認。 | ||
+ | |||
+ | printf("test_jis.txtテキストファイルの中身\n"); | ||
+ | fgetpos(pfileText, pfposStartPos); | ||
+ | while(!feof(pfileText)){ | ||
+ | nSize = nSize + nFeedCnt * 1024; | ||
+ | nFeedCnt++; | ||
+ | *psizeRuturnValue = fread(pcStrStream, sizeof(char), 1024, pfileText);//最終行がEOFのみの場合に失敗して1行前の値が残ることに注意。 | ||
+ | fgetpos(pfileText, fposPos); | ||
+ | for(int i = 0; i < *fposPos; i++){ | ||
+ | printf("%02x:",0x000000FF & *(pcStrStream + i)); | ||
+ | } | ||
+ | } | ||
+ | printf("[EOF]"); | ||
+ | printf("\n"); | ||
+ | |||
+ | nSize = nSize + (int)*fposPos - ((nFeedCnt - 1) * 1024); | ||
+ | fsetpos(pfileText, pfposStartPos); | ||
+ | pcStrFile = new char[nSize + 1]; | ||
+ | while(!feof(pfileText)){ | ||
+ | *psizeRuturnValue = fread(pcStrFile, sizeof(char), nSize + 1, pfileText);//最終行がEOFのみの場合に失敗して1行前の値が残ることに注意。 | ||
+ | for(int i = 0; i < nSize; i++){ | ||
+ | printf("%02x:",0x000000FF & *(pcStrFile + i)); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | printf("[EOF]"); | ||
+ | printf("\n"); | ||
+ | fgetpos(pfileText, fposPos); | ||
+ | printf("fpos-> %04d\npReturnValue-> %04d\n", *fposPos, *psizeRuturnValue); //ファイルを開いた時点でのポジションの確認。 | ||
+ | |||
+ | |||
+ | nCloseCnt = fclose(pfileText); | ||
+ | printf("nCloseErr->%d\n", nCloseCnt); | ||
+ | printf("\n"); | ||
+ | |||
+ | UConverter* ucnvTest; | ||
+ | UErrorCode uerrorNum; | ||
+ | int nStrSize; | ||
+ | int nStrResultSize; | ||
+ | nStrSize = nSize; | ||
+ | |||
+ | std::wstring stringCnvResult(nStrSize, L'\0'); | ||
+ | |||
+ | ucnvTest = ucnv_open("iso-2022-jp", &uerrorNum); | ||
+ | nStrResultSize = ucnv_toUChars( | ||
+ | ucnvTest, | ||
+ | &stringCnvResult[0], stringCnvResult.size(), // 変換先のポインタとサイズ | ||
+ | &pcStrFile[0], nStrSize, // 変換元のポインタとサイズ | ||
+ | &uerrorNum | ||
+ | ); | ||
+ | stringCnvResult.resize(nStrResultSize); | ||
+ | ucnv_close(ucnvTest); | ||
+ | _tprintf(_T("%s\n"), stringCnvResult.c_str()); | ||
+ | printf("\n"); | ||
+ | return 0; | ||
+ | } | ||
+ | </syntaxhighlight2> | ||
+ | 出力結果 | ||
+ | <syntaxhighlight2 lang="text"> | ||
+ | ★UTF8のBOM無しテキストの読み込み | ||
+ | Error?->0 | ||
+ | fpos-> 0000 | ||
+ | 文字コードUTF-16LE->3054:306f:3093:3092:98df:3079:305f:3088:3002:000d:000a:0000: | ||
+ | utf8N.txtテキストファイルの中身とその他の情報出力 | ||
+ | ごはんを食べたよ。 | ||
+ | (ごはんを食べたよ。 | ||
+ | ) | ||
+ | 文字コードUTF-16LE->3054:306f:3093:3092:98df:3079:305f:3088:3002:000a:0000:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:fpos-> 0029 | ||
+ | |||
+ | ( | ||
+ | ) | ||
+ | 文字コードUTF-16LE->000a:0000:3093:3092:98df:3079:305f:3088:3002:000a:0000:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:fpos-> 0031 | ||
+ | |||
+ | ( | ||
+ | ) | ||
+ | 文字コードUTF-16LE->000a:0000:3093:3092:98df:3079:305f:3088:3002:000a:0000:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:fpos-> 0033 | ||
+ | それだけだよ。 | ||
+ | (それだけだよ。 | ||
+ | ) | ||
+ | 文字コードUTF-16LE->305d:308c:3060:3051:3060:3088:3002:000a:0000:000a:0000:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:fpos-> 0056 | ||
+ | それだけだよ。 | ||
+ | ((null)) | ||
+ | 文字コードUTF-16LE->305d:308c:3060:3051:3060:3088:3002:000a:0000:000a:0000:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:fpos-> 0056 | ||
+ | [EOF] | ||
+ | nCloseErr->0 | ||
+ | nCloseCnt->0 | ||
+ | |||
+ | ★UTF8NのBOM有りテキストの読み込み | ||
+ | Error?->0 | ||
+ | fpos-> 0003 | ||
+ | utf8.txtテキストファイルの中身 | ||
+ | ごはんを食べたよ。 | ||
+ | |||
+ | |||
+ | それだけだよ。 | ||
+ | [EOF] | ||
+ | nCloseErr->0 | ||
+ | |||
+ | ★UTF16LEのBOM有りテキストの読み込み | ||
+ | Error?->0 | ||
+ | fpos-> 0002 | ||
+ | utf8.txtテキストファイルの中身 | ||
+ | ごはんを食べたよ。 | ||
+ | |||
+ | |||
+ | それだけだよ。 | ||
+ | [EOF] | ||
+ | nCloseErr->0 | ||
+ | |||
+ | ★ShiftJISテキストの読み込み | ||
+ | Error?->0 | ||
+ | fpos-> 0000 | ||
+ | test.txtテキストファイルの中身 | ||
+ | ごはんを食べたよ。 | ||
+ | |||
+ | |||
+ | それだけだよ。 | ||
+ | [EOF] | ||
+ | nCloseErr->0 | ||
+ | |||
+ | ★JISテキストの読み込み | ||
+ | Error?->0 | ||
+ | fpos-> 0000 | ||
+ | test_jis.txtテキストファイルの中身 | ||
+ | 1b:24:42:24:34:24:4f:24:73:24:72:3f:29:24:59:24:3f:24:68:21:23:1b:28:4a:0d:0a:0d:0a:0d:0a:1b:24:42:24:3d:24:6c:24:40:24:31:24:40:24:68:21:23 | ||
+ | :1b:28:4a:0d:0a:[EOF] | ||
+ | 1b:24:42:24:34:24:4f:24:73:24:72:3f:29:24:59:24:3f:24:68:21:23:1b:28:4a:0d:0a:0d:0a:0d:0a:1b:24:42:24:3d:24:6c:24:40:24:31:24:40:24:68:21:23 | ||
+ | :1b:28:4a:0d:0a:[EOF] | ||
+ | fpos-> 0052 | ||
+ | pReturnValue-> 0000 | ||
+ | nCloseErr->0 | ||
+ | |||
+ | ごはんを食べたよ。 | ||
+ | |||
+ | |||
+ | それだけだよ。 | ||
+ | |||
+ | </syntaxhighlight2> | ||
+ | という感じです。ごはんを食べたよ それだけだよ。というサンプルの文字列に特に深い意味はありませんが、Windowsは改行コードにCR LFを使うのが一般的です。しかしながら、ファイルから取り込んできた文字列にでは\r 0x0dは無くなって\nにあたる0x0aだけが残る仕様になっています。これらの改行復帰コードを厳密に扱う場合には書き込みするときや、文字列操作時に工夫が必要になります。文字コードがどんなふうに扱われているのか、厳密にどうなっているのか調べるためにも、時々は文字コードそのものを出力して確かめるのも大事なのではないかと思います。人間様にわかる文字だけを出力していたのでは、コンピュータを正確にあやつることは難しいです。JISの変換ではファイルオープン時にバイナリで開いています。これをchar型の変数に格納して、ICUのJIS→UNICODE変換を実施しています。 | ||
+ | |||
+ | |||
+ | テキストファイルをバイナリで読み込む場合には区切りが大事です。動的に生成できる文字列配列の大きさはint型の範囲が限界ですので、ひとつだけで扱おうとするのは無理がありますし、int型くらい大きいサイズのメモリ確保は無理があります。もう少し小さい単位で文字列を扱える工夫が必要になります。JISテキストファイルなら改行コードまでの大きさくらいが良いと思います。文字列の中に改行コードが見つかるまで文字数を計算して、それでメモリ確保をし、JIS文字列を変換して、作業用の文字列配列に格納するといった、そういう仕組みにするだけのことです。このプログラムはテキストエディタやファイルローダとしての役割を担うものではないので、そこまでの具体的な拡張には挑戦しませんでした。実際の組み込みでは、プログラムが扱うデータの大きさにちょうどよい区切りを準備することになると思います。 | ||
+ | まぁこのままでもかなり大きさまで扱えるので、コンソールで遊ぶ程度ならこれでもいいんではないでしょうか?それよか、メモリ確保がうまくいかない場合の例外処理とか追加しますかね。そのあたりの説明はまた別の項目になるかと思います。 | ||
+ | |||
+ | |||
+ | ファイル読み込み時に文字コードセットが判明しているサンプルプログラムのようなケースはプログラムが簡単でしたが、もともとのファイル形式を自動判別して読み込むプログラムに対応しようとすると、またひとつ大変さが増します。自動判別ができないのはutf-8で書かれた英字だけのファイルを開いた場合で、ShiftJISとするのが最適なのか?UTF-8として開くのが最適なのかは、ユーザにあらかじめ決めてもらった方が良いかもしれません。一度でも日本語が使われていれば、おのずと判定ができるわけですが、すべての文字をチェックして英字以外の範囲の文字コードを見つけて、それが、どの文字コードなのかを判別する仕組みが必要です。 | ||
+ | |||
+ | |||
+ | おもしろそうですが、文字コードに詳しくないので、自分はまだその手法をしりません。また今度、考えてみようと思います。文字化けしてるコードをみて、あーこれはもともとはこのコードだったんだろうなという感覚はあるんですが、それと似たような法則があるんでしょうね。結局、この判定もICUでできちゃうんですけどね。これも時間があればやってみたいと思います。 | ||
+ | |||
+ | |||
+ | 次はファイル出力にあたる書き込みですね。 | ||
+ | <syntaxhighlight2 lang="cpp" line start="1"> | ||
+ | //JISからUTF-16LEへの変換処理 | ||
+ | |||
+ | UConverter* ucnvTest; | ||
+ | UErrorCode uerrorNum; | ||
+ | int nStrSize; | ||
+ | int nStrResultSize; | ||
+ | char pcStrUTF16LEBOM[] = "\xFF\xFE";//\xエスケープシーケンスはx以降の16進数とした文字コードを示すもの。1バイトの文字コード指定で利用できます。 | ||
+ | char pcStrUTF8BOM[] = "\xEF\xBB\xBF"; | ||
+ | nStrSize = nSize; | ||
+ | |||
+ | std::wstring stringCnvResult(nStrSize, L'\0'); | ||
+ | |||
+ | ucnvTest = ucnv_open("iso-2022-jp", &uerrorNum); | ||
+ | nStrResultSize = ucnv_toUChars( | ||
+ | ucnvTest, | ||
+ | &stringCnvResult[0], stringCnvResult.size(), // 変換先のポインタとサイズ | ||
+ | &pcStrFile[0], nStrSize, // 変換元のポインタとサイズ | ||
+ | &uerrorNum | ||
+ | ); | ||
+ | stringCnvResult.resize(nStrResultSize); | ||
+ | ucnv_close(ucnvTest); | ||
+ | _tprintf(_T("%s\n"), stringCnvResult.c_str()); | ||
+ | printf("\n"); | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //★UTF16LEのTextモードでの書き込み | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | //\n 0x0Aが \r\nに変換されるため、Binaryモードで読み込んだ\r\nを保持した文字列から | ||
+ | //変換した文字列をテキストモードで書き込むと\r\r\nのように2重復帰が書き込まれる。 | ||
+ | //テキストエディタでは\rひとつでも、改行されるため \r と \r\nで2つ改行になる。 | ||
+ | |||
+ | errNo = _wfopen_s( &pfileText, pwcStrFilePathNewTexttoBinary, L"w,ccs=UTF-16LE"); | ||
+ | fputws(stringCnvResult.c_str(), pfileText); | ||
+ | fclose(pfileText); | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //★UTF16LEのBinaryモードテキストの書き込み | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | errNo = _wfopen_s( &pfileText, pwcStrFilePathNewUTF16LE, L"wb"); | ||
+ | fputs(pcStrUTF16LEBOM,pfileText); | ||
+ | fputws(stringCnvResult.c_str(), pfileText); | ||
+ | fclose(pfileText); | ||
+ | |||
+ | //UnicodeUTF-16LEのutf-8への変換処理 | ||
+ | ucnvTest = ucnv_open("UTF-8", &uerrorNum); | ||
+ | |||
+ | nStrSize = stringCnvResult.size(); | ||
+ | std::string stringCnvResult3(ucnv_getMaxCharSize(ucnvTest) * nStrSize , L'\0'); | ||
+ | |||
+ | |||
+ | nStrResultSize = ucnv_fromUChars( | ||
+ | ucnvTest, | ||
+ | &stringCnvResult3[0], stringCnvResult3.size(), // 変換先のポインタとサイズ | ||
+ | &stringCnvResult[0], nStrSize, // 変換元のポインタとサイズ | ||
+ | &uerrorNum | ||
+ | ); | ||
+ | stringCnvResult3.resize(nStrResultSize); | ||
+ | ucnv_close(ucnvTest); | ||
+ | printf("%s\n", stringCnvResult3.c_str()); | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //★UTF8のBOM無しテキストの書き込み | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | errNo = _wfopen_s( &pfileText, pwcStrFilePathNewUTF8, L"wb"); | ||
+ | //fputs(pcStrUTF8BOM,pfileText); | ||
+ | fputs(stringCnvResult3.c_str(), pfileText); | ||
+ | fclose(pfileText); | ||
+ | |||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //★UTF8のBOM有りテキストの書き込み | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | errNo = _wfopen_s( &pfileText, pwcStrFilePathNewUTF8BOM, L"wb"); | ||
+ | fputs(pcStrUTF8BOM,pfileText); | ||
+ | fputs(stringCnvResult3.c_str(), pfileText); | ||
+ | fclose(pfileText); | ||
+ | </syntaxhighlight2> | ||
+ | 先述の読み込み処理に続けてのプログラムになります。ファイルオープンモードでwを指定して、fputs関数でchar型の書き込み、fputwsでwchar_t型の書き込みをするような形式です。モードaで追記なのでファイル末尾から追記されます。ファイルの先頭に追加するときはBOMコードの後の所にファイルポジションをfsetpos関数で移動してからfputws/fputsで書き込むと良いでしょう。新規のファイル作成となるモードwのバイナリモードwbでは、BOMコードを付与しなければならないケースも出てきます。fputsでBOMコードを保持した文字列を引数にすると良いです。bを付けないテキストモードでの書き込みでは、ccs=UTF-8やccs=UTF-16LEを指定すると自動でBOMコードを追記してくれますので、そのままUTF-16ならwchar_t型の文字列を書き出せばよいです。但し、バイナリモードで読み込んだ文字列は\r\nがそのまま文字列になっているので、書き出し時に後ろの\nが\r\nに変換され、\r\r\nになってしまうので、バイナリモードで読み込んだ文字をテキストモードで書き出すのはやめた方がいいです。どうしても相互乗り換えするのであれば、改行コードの置換処理が必要です。UTF-8のテキストモード書き込みでもユニコードのUTF-16LE形式で書き込むことでUTF-8に変換されますので、プログラム内部ではUnicodeで文字列を扱った方が効率が良いと思います。テキストモードでサポートしない文字コードのような特殊な形式に変換する場合はバイナリモードで文字列を読み込んで、変換処理を実施し、char型に格納した文字コードをバイナリモードで書き出すと良いでしょう。サンプルプログラムではテキストモードで読み込んだJIS文字をUnicodeに変換しUTF-16テキストモードで書き込んだ失敗例をプログラムにしてあります。ファイルオープンモードをうまく使いこなすことと、Unicode以外の文字列はchar型でバイナリとして扱うところがポイントです。変換処理はICUに任せればかなり柔軟な入出力処理が作れると思います。 | ||
+ | |||
+ | |||
+ | ファイルオープンモードについてですが、r、w、a、rb、wb、ab の他にもr+ のように+記号を付けるパターンがあります。この場合、r+ 既存ファイルに読み込み上書き、w+ 新規ファイルで読み書き、a+ 既存ファイルに読み追記ができます。cをつけるとflush関数による反映ですべての操作が確定しファイルに反映するモードになります。通常はcではないモードのnが規定値になっています。bを指定しない場合も実際はtが規定値として扱われています。他にもディスクにファイルを残さずメモリ上だけでファイルの操作をするためにT(ファイル生成されない)やD(ファイルポインタを閉じると削除されるファイル)といった一時ファイル指定もありますし、シーケンシャルアクセス最適化のSにランダムアクセス最適化のR、子プロセスに継承しないNといった非常に難しいコアなオプションもあります。シーケンシャルやランダムアクセスについては記録するディスクの仕組みにもよりますが、通常はシーケンシャルの方が読み取り効率が良いはずですが、ランダムに配置された方が待ち時間が少なくなるというケースもあります。大容量・大量のファイルを扱う場合によく調べて選択するとよいかもしれません。Nは違うプログラム(子プロセス)からファイルポインタを2重に参照させないというようなオプションかと思います。やってみたことないので、具体的な例はここでは示せません。やはり経験が少ないと細かいところまでは説明できないですね。無念。 | ||
+ | |||
+ | |||
+ | ここの長ったらしい文字列処理の説明の総括的なプログラミングになっているかと思います。全部理解してこそ、やりきれる処理です。文字列処理のプログラムを普段作らない自分でもこの程度なら理解しておきたいものです。ここのサンプルは直線的なプログラムで無駄の多いサンプルです。みなさんはもっともっと効率のいい文字列処理をやって下さい。ここでは関数の引数や、クラスの考え方をあまり知らなくても、文字列処理ができるように、あまり多くの技術を使わないそういう無駄なサンプルになっていますが、上から順番に処理していくだけなので、処理の順番は理解しやすいようになっているのではないかと自負するところです。あとは文字コードの自動判定くらいを触れて、文字列処理に関するこの記事は終了にしたいなぁと思います。誰も読まないかもしれないのに、よくこんなにウダウダと長ったらしい文章を書いたなぁ。恐るべしだ。でも、こういううだうだした説明ともっと若いときに出会っていたら、もっと手早く理解できたのになぁと自分は思います。この長い文書が誰かの役に立っていたなら幸せなことです。 | ||
+ | |||
+ | |||
+ | ICUによる文字コード自動判定のプログラムは以下のとおりです。 | ||
+ | <syntaxhighlight2 lang="cpp" line start="1"> | ||
+ | #pragma once | ||
+ | #include "stdafx.h" | ||
+ | #include <stdlib.h> | ||
+ | #include <string> //std::string型定義 | ||
+ | #include <mbstring.h> //mbs***関数 | ||
+ | #include <iostream> //cpp cout etc 一般入出力関数 | ||
+ | #include <locale> //Locale関数 | ||
+ | #include <tchar.h> //TCHAR型+_tcs***関数 | ||
+ | #include "atlstr.h" //CString,CStringA,CStringWおよびLPTSTR,LPWSTR,LPSTR,LPCTSTR,LPCWSTR,LPCSTRの定義プリプロセッサ | ||
+ | #include "atlbase.h" //同上 | ||
+ | #include "cstringt.h" //CStringTの定義プリプロセッサ | ||
+ | #include <vector> //Vector型テンプレートクラス | ||
+ | |||
+ | #include <sys/timeb.h> //Timeb型構造体 | ||
+ | |||
+ | //_bstr_t型を利用するプリプロセッサ(ライブラリはデバッグモードとリリースモード個別設定) | ||
+ | #include "comutil.h" | ||
+ | |||
+ | #ifdef _DEBUG | ||
+ | #pragma comment(lib, "comsuppwd.lib") | ||
+ | #else | ||
+ | #pragma comment(lib, "comsuppw.lib") | ||
+ | #endif | ||
+ | //_bstr_t _End | ||
+ | |||
+ | //ICU ucnvプリプロセッサ(ライブラリはデバッグモードとリリースモード個別設定) | ||
+ | #include <unicode/ucnv.h> //ucnv文字コード変換ライブラリヘッダ | ||
+ | #include <unicode/translit.h> //文字変換ライブラリヘッダ | ||
+ | #include <unicode/regex.h> //正規表現 | ||
+ | #include <unicode/ucsdet.h> //文字コード判定 | ||
+ | |||
+ | #ifdef _DEBUG | ||
+ | //#pragma comment(lib, "icudt.lib") | ||
+ | #pragma comment(lib, "icuind.lib") //ICU Transliterate関数を使うために必要なライブラリ 正規表現関数も | ||
+ | #pragma comment(lib, "icuucd.lib") //ICU ucnvを使うために必要なライブラリ | ||
+ | //#pragma comment(lib, "icuiod.lib") | ||
+ | #else | ||
+ | //#pragma comment(lib, "icudt.lib") | ||
+ | #pragma comment(lib, "icuind.lib") //ICU Transliterate関数を使うために必要なライブラリ 正規表現関数も | ||
+ | #pragma comment(lib, "icuuc.lib") //ICU ucnvを使うために必要なライブラリ | ||
+ | //#pragma comment(lib, "icuio.lib") | ||
+ | #endif | ||
+ | //ICU ucnv _End | ||
+ | |||
+ | #include "UnicodeConverter.h" | ||
+ | |||
+ | using namespace std; | ||
+ | |||
+ | int _tmain(int argc, _TCHAR* argv[]) | ||
+ | { | ||
+ | _tsetlocale(LC_ALL, _T("Japanese")); //ロケールセットすると_l関数でロケール指定しなくても日本語が使われます。 | ||
+ | |||
+ | _locale_t localeJpanease; | ||
+ | localeJpanease = _create_locale(LC_ALL, "Japanese"); | ||
+ | |||
+ | FILE* pfileText; | ||
+ | fpos_t* fposPos = new fpos_t; | ||
+ | errno_t errNo; | ||
+ | size_t* psizeRuturnValue = new size_t; | ||
+ | |||
+ | wchar_t pwcStrFilePath[] = L"C:\\Users\\Administrator\\Documents\\マイ インフォメーション\\ファイル入出力\\test_utf16LE.txt"; | ||
+ | char* pcStrStream; | ||
+ | pcStrStream = new char[1024]; | ||
+ | int nCloseResult = 0; | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //★テキストの読み込み | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | //int型でchar配列のサイズを動的に確保ができるので、int型の範囲のファイルなら | ||
+ | //一度に格納できるプログラムになっています。intの範囲を超えると動的メモリ確保で | ||
+ | //失敗します。その先の工夫はまた別途考える必要があります。少し筒変換したり…。 | ||
+ | |||
+ | int nSize = 0; | ||
+ | int nFeedCnt = 0; | ||
+ | |||
+ | char* pcStrFile; | ||
+ | fpos_t* pfposStartPos = new fpos_t; | ||
+ | printf("★テキストの読み込み\n"); | ||
+ | errNo = _wfopen_s( &pfileText, pwcStrFilePath, L"rb"); | ||
+ | printf("Error?->%d\n", errNo); | ||
+ | |||
+ | fgetpos(pfileText, fposPos); | ||
+ | printf("fpos-> %04d\n", *fposPos); //ファイルを開いた時点でのポジションの確認。 | ||
+ | |||
+ | printf("test.txtテキストファイルの中身\n"); | ||
+ | fgetpos(pfileText, pfposStartPos); | ||
+ | while(!feof(pfileText)){ | ||
+ | nSize = nSize + nFeedCnt * 1024; | ||
+ | nFeedCnt++; | ||
+ | *psizeRuturnValue = fread(pcStrStream, sizeof(char), 1024, pfileText);//最終行がEOFのみの場合に失敗して1行前の値が残ることに注意。 | ||
+ | fgetpos(pfileText, fposPos); | ||
+ | for(int i = 0; i < *fposPos; i++){ | ||
+ | printf("%02x:",0x000000FF & *(pcStrStream + i)); | ||
+ | } | ||
+ | } | ||
+ | printf("[EOF]"); | ||
+ | printf("\n"); | ||
+ | |||
+ | nSize = nSize + (int)*fposPos - ((nFeedCnt - 1) * 1024); | ||
+ | fsetpos(pfileText, pfposStartPos); | ||
+ | pcStrFile = new char[nSize + 1]; | ||
+ | while(!feof(pfileText)){ | ||
+ | *psizeRuturnValue = fread(pcStrFile, sizeof(char), nSize + 1, pfileText);//最終行がEOFのみの場合に失敗して1行前の値が残ることに注意。 | ||
+ | for(int i = 0; i < nSize; i++){ | ||
+ | printf("%02x:",0x000000FF & *(pcStrFile + i)); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | printf("[EOF]"); | ||
+ | printf("\n"); | ||
+ | fgetpos(pfileText, fposPos); | ||
+ | printf("fpos-> %04d\npReturnValue-> %04d\n", *fposPos, *psizeRuturnValue); //ファイルを開いた時点でのポジションの確認。 | ||
+ | |||
+ | |||
+ | nCloseResult = fclose(pfileText); | ||
+ | printf("nCloseErr->%d\n", nCloseResult); | ||
+ | printf("\n"); | ||
+ | |||
+ | UConverter* ucnvTest; | ||
+ | UErrorCode uerrorNum = U_ZERO_ERROR; | ||
+ | int nStrSize; | ||
+ | int nStrResultSize; | ||
+ | char pcStrUTF16LEBOM[] = "\xFF\xFE"; | ||
+ | char pcStrUTF8BOM[] = "\xEF\xBB\xBF"; | ||
+ | nStrSize = nSize; | ||
+ | |||
+ | UCharsetDetector* pucsetdetecDetector = ucsdet_open(&uerrorNum); | ||
+ | ucsdet_setText(pucsetdetecDetector, pcStrFile, nSize, &uerrorNum); | ||
+ | |||
+ | int32_t int32FindCharSetCnt = 0; | ||
+ | const UCharsetMatch* pucsetmatchStrCode = ucsdet_detect(pucsetdetecDetector, &uerrorNum); | ||
+ | |||
+ | const char* cpcDetectStrCodeName; | ||
+ | const char* cpcDetectStrCodeLanguage; | ||
+ | cpcDetectStrCodeName = ucsdet_getName(pucsetmatchStrCode, &uerrorNum);//文字コード名 ICUの文字コードセット名に適した形式。 | ||
+ | cpcDetectStrCodeLanguage = ucsdet_getLanguage(pucsetmatchStrCode, &uerrorNum); | ||
+ | |||
+ | printf("★ICU Code Detectorによるテキストの文字コード自動判定\n"); | ||
+ | printf("CodeName->%s\n",cpcDetectStrCodeName); | ||
+ | printf("CodeLang->%s\n",cpcDetectStrCodeLanguage);//RFC3066コードを取得できる。 | ||
+ | |||
+ | //Shift_JISからUTF-16LEへの変換処理 | ||
+ | |||
+ | //先頭がBOMコードなら変換する文字の先頭アドレスをBOMコードの長さを割り出し、nShiftByteに記録。 | ||
+ | int nShiftByte = 0; | ||
+ | if(strlen(pcStrFile) >= 3){ | ||
+ | if(strncmp(pcStrFile,pcStrUTF8BOM,3) == 0){ | ||
+ | nShiftByte = 3; | ||
+ | } | ||
+ | } | ||
+ | if(strlen(pcStrFile) >= 2){ | ||
+ | if(strncmp(pcStrFile,pcStrUTF16LEBOM,2) == 0){ | ||
+ | nShiftByte = 2; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | std::wstring stringCnvResult(nStrSize, L'\0'); | ||
+ | |||
+ | ucnvTest = ucnv_open(cpcDetectStrCodeName, &uerrorNum);//変換する文字コードは自動判定で取得した文字コード。 | ||
+ | nStrResultSize = ucnv_toUChars( | ||
+ | ucnvTest, | ||
+ | &stringCnvResult[0], stringCnvResult.size(), // 変換先のポインタとサイズ | ||
+ | &pcStrFile[0 + nShiftByte], nStrSize - nShiftByte, // 変換元のポインタとサイズ BOMサイズがnShiftByteに格納されている。 | ||
+ | &uerrorNum | ||
+ | ); | ||
+ | stringCnvResult.resize(nStrResultSize); | ||
+ | ucnv_close(ucnvTest); | ||
+ | ucsdet_close(pucsetdetecDetector); | ||
+ | _tprintf(_T("%s[EOF]"), stringCnvResult.c_str()); | ||
+ | printf("\n"); | ||
+ | return 0; | ||
+ | } | ||
+ | </syntaxhighlight2> | ||
+ | 出力結果 utf16LEのテキストを指定した場合。 | ||
+ | <syntaxhighlight2 lang="text"> | ||
+ | ★テキストの読み込み | ||
+ | Error?->0 | ||
+ | fpos-> 0000 | ||
+ | test.txtテキストファイルの中身 | ||
+ | ff:fe:54:30:6f:30:93:30:92:30:df:98:79:30:5f:30:88:30:02:30:0d:00:0a:00:0d:00:0a:00:0d:00:0a:00:5d:30:8c:30:60:30:51:30:60:30:88:30:02:30:0d:00:0a:00:[EOF] | ||
+ | ff:fe:54:30:6f:30:93:30:92:30:df:98:79:30:5f:30:88:30:02:30:0d:00:0a:00:0d:00:0a:00:0d:00:0a:00:5d:30:8c:30:60:30:51:30:60:30:88:30:02:30:0d:00:0a:00:[EOF] | ||
+ | fpos-> 0050 | ||
+ | pReturnValue-> 0000 | ||
+ | nCloseErr->0 | ||
+ | |||
+ | ★ICU Code Detectorによるテキストの文字コード自動判定 | ||
+ | CodeName->UTF-16LE | ||
+ | CodeLang-> | ||
+ | ごはんを食べたよ。 | ||
+ | |||
+ | |||
+ | それだけだよ。 | ||
+ | [EOF] | ||
+ | </syntaxhighlight2> | ||
+ | 出力結果 utf8のテキストを指定した場合。 | ||
+ | <syntaxhighlight2 lang="text"> | ||
+ | ★テキストの読み込み | ||
+ | Error?->0 | ||
+ | fpos-> 0000 | ||
+ | test.txtテキストファイルの中身 | ||
+ | ef:bb:bf:e3:81:94:e3:81:af:e3:82:93:e3:82:92:e9:a3:9f:e3:81:b9:e3:81:9f:e3:82:88:e3:80:82:0d:0a:0d:0a:0d:0a:e3:81:9d:e3:82:8c:e3:81:a0:e3:81:91:e3:81:a0:e3:82:88:e3:80:82:0d:0a:[EOF] | ||
+ | ef:bb:bf:e3:81:94:e3:81:af:e3:82:93:e3:82:92:e9:a3:9f:e3:81:b9:e3:81:9f:e3:82:88:e3:80:82:0d:0a:0d:0a:0d:0a:e3:81:9d:e3:82:8c:e3:81:a0:e3:81:91:e3:81:a0:e3:82:88:e3:80:82:0d:0a:[EOF] | ||
+ | fpos-> 0059 | ||
+ | pReturnValue-> 0000 | ||
+ | nCloseErr->0 | ||
+ | |||
+ | ★ICU Code Detectorによるテキストの文字コード自動判定 | ||
+ | CodeName->UTF-8 | ||
+ | CodeLang-> | ||
+ | ごはんを食べたよ。 | ||
+ | |||
+ | |||
+ | それだけだよ。 | ||
+ | [EOF] | ||
+ | </syntaxhighlight2> | ||
+ | 出力結果 JISのテキストを指定した場合。 | ||
+ | <syntaxhighlight2 lang="text"> | ||
+ | ★テキストの読み込み | ||
+ | Error?->0 | ||
+ | fpos-> 0000 | ||
+ | test.txtテキストファイルの中身 | ||
+ | 1b:24:42:24:34:24:4f:24:73:24:72:3f:29:24:59:24:3f:24:68:21:23:1b:28:4a:0d:0a:0d:0a:0d:0a:1b:24:42:24:3d:24:6c:24:40:24:31:24:40:24:68:21:23:1b:28:4a:0d:0a:[EOF] | ||
+ | 1b:24:42:24:34:24:4f:24:73:24:72:3f:29:24:59:24:3f:24:68:21:23:1b:28:4a:0d:0a:0d:0a:0d:0a:1b:24:42:24:3d:24:6c:24:40:24:31:24:40:24:68:21:23:1b:28:4a:0d:0a:[EOF] | ||
+ | fpos-> 0052 | ||
+ | pReturnValue-> 0000 | ||
+ | nCloseErr->0 | ||
+ | |||
+ | ★ICU Code Detectorによるテキストの文字コード自動判定 | ||
+ | CodeName->ISO-2022-JP | ||
+ | CodeLang-> | ||
+ | ごはんを食べたよ。 | ||
+ | |||
+ | |||
+ | それだけだよ。 | ||
+ | [EOF] | ||
+ | </syntaxhighlight2> | ||
+ | 出力結果 ShiftJISのテキストを指定した場合。 | ||
+ | <syntaxhighlight2 lang="text"> | ||
+ | ★テキストの読み込み | ||
+ | Error?->0 | ||
+ | fpos-> 0000 | ||
+ | test.txtテキストファイルの中身 | ||
+ | 82:b2:82:cd:82:f1:82:f0:90:48:82:d7:82:bd:82:e6:81:42:0d:0a:0d:0a:0d:0a:82:bb:82:ea:82:be:82:af:82:be:82:e6:81:42:0d:0a:[EOF] | ||
+ | 82:b2:82:cd:82:f1:82:f0:90:48:82:d7:82:bd:82:e6:81:42:0d:0a:0d:0a:0d:0a:82:bb:82:ea:82:be:82:af:82:be:82:e6:81:42:0d:0a:[EOF] | ||
+ | fpos-> 0040 | ||
+ | pReturnValue-> 0000 | ||
+ | nCloseErr->0 | ||
+ | |||
+ | ★ICU Code Detectorによるテキストの文字コード自動判定 | ||
+ | CodeName->Shift_JIS | ||
+ | CodeLang->ja | ||
+ | ごはんを食べたよ。 | ||
+ | |||
+ | |||
+ | それだけだよ。 | ||
+ | [EOF] | ||
+ | </syntaxhighlight2> | ||
+ | とこのような感じになります。書き出すときには文字コード別にBOMを付与する処理が必要になりますが、自動判別によって、かなりたくさんの文字コードのテキストファイルを自動で読み込むことができるようになります。やや便利なコンソールアプリになったのかもしれません。そんな得体の知れないテキストファイルが転がっているかどうかは知りませんが…。BOMコードの種類にはUTF-16BEもあるので、このあたりにも対応したプログラムにするともっといいかもしれませんね。 | ||
+ | 今回のサンプルでは完璧な変換をしてくれましたが、ややこしい文字構成ばかりのテキストファイルになってくると間違えることもあります。そのためICUでは文字コード一致率みたいなランキングを作ってくれる関数もありまして、ucsdet_detect関数の代わりにucsdet_detectAllという関数で UCharsetMatch**型を戻り値にするものがあります。ポインタのポインタってことは、配列ってことになります。ucsdete_getName関数で、引数のその配列の要素を渡せば、それぞれの文字コード名が一覧されます。具体的には以下のような要領になります。 | ||
+ | <syntaxhighlight2 lang="cpp" line start="1"> | ||
+ | int32_t int32FindCharSetCnt = 0; | ||
+ | int32_t int32Confidence = 0; | ||
+ | const UCharsetMatch* pucsetmatchStrCode = ucsdet_detect(pucsetdetecDetector, &uerrorNum); | ||
+ | const UCharsetMatch** ppucsetmatchStrCode = ucsdet_detectAll(pucsetdetecDetector, &int32FindCharSetCnt, &uerrorNum); | ||
+ | |||
+ | const char* cpcDetectStrCodeName; | ||
+ | const char* cpcDetectStrCodeLanguage; | ||
+ | |||
+ | for(int i = 0; i < int32FindCharSetCnt; i++){ | ||
+ | int32Confidence = ucsdet_getConfidence(ppucsetmatchStrCode[i], &uerrorNum);0~100で表される信頼値 | ||
+ | cpcDetectStrCodeName = ucsdet_getName(ppucsetmatchStrCode[i], &uerrorNum);//文字コード名 ICUの文字コードセット名に適した形式。 | ||
+ | cpcDetectStrCodeLanguage = ucsdet_getLanguage(ppucsetmatchStrCode[i], &uerrorNum); | ||
+ | printf("CodeConf->%d\n",int32Confidence); | ||
+ | printf("CodeName->%s\n",cpcDetectStrCodeName); | ||
+ | printf("CodeLang->%s\n",cpcDetectStrCodeLanguage);//RFC3066コードを取得できる。 | ||
+ | } | ||
+ | </syntaxhighlight2> | ||
+ | のようにするとConfidenceの値が大きいほど一致率が高いものとして確認ができます。全部を一覧するにはfor文で0~int32FindCharSetCnt -1までの要素を確認するとよいです。 | ||
+ | 出力結果 UTF-16LEのファイル。 | ||
+ | <syntaxhighlight2 lang="text"> | ||
+ | CodeConf->100 | ||
+ | CodeName->UTF-16LE | ||
+ | CodeLang-> | ||
+ | CodeConf->23 | ||
+ | CodeName->windows-1252 | ||
+ | CodeLang->es | ||
+ | CodeConf->23 | ||
+ | CodeName->windows-1250 | ||
+ | CodeLang->cs | ||
+ | CodeConf->10 | ||
+ | CodeName->UTF-16BE | ||
+ | CodeLang-> | ||
+ | </syntaxhighlight2> | ||
+ | となります。 | ||
+ | |||
+ | =='''文字列と数値の変換'''== | ||
+ | 実際のアプリケーションでは、数値の入力を行う部分でも、文字コードとして入力がなされ、各種のエディタや、エディットコントロール、入力画面からは文字としてテキストから渡されます。このように取り扱われる文字列としての数値を、プログラミング言語の数を扱う型に格納する技術が必要になります。 | ||
+ | |||
+ | atoi、atol、atofのような標準関数で簡単に文字列を数値に変換することができます。逆に数値を文字列に変換する関数もitoaやltoa、ftoaのように準備されていますが非標準関数となっています。ほぼ標準で準備されています。同じことがprintf関数のような関数でva_listという可変長引数の型を引数とするvsprintf(vscprintf:文字数カウント用)関数あるい通常のsprintf(scprintf:文字数カウント)関数を使って実現できます。ここでは、使い方のややこしいvsprintfを使ってみました。数値の文字列化に関してはitoaなどの関数よりも書式設定ができる分、応用が利くので、自分ならこういうものを活用します。atoiのような関数はC++ではstd::atoiのような名前空間の中に定義されています。使い方は同じです。 | ||
+ | |||
+ | では、以下がサンプルになります。 | ||
+ | <syntaxhighlight2 lang="cpp" line start="1"> | ||
+ | #pragma once | ||
+ | #include "stdafx.h" | ||
+ | #include <stdlib.h> | ||
+ | #include <string> //std::string型定義 | ||
+ | #include <mbstring.h> //mbs***関数 | ||
+ | #include <iostream> //cpp cout etc 一般入出力関数 | ||
+ | #include <locale> //Locale関数 | ||
+ | #include <tchar.h> //TCHAR型+_tcs***関数 | ||
+ | #include "atlstr.h" //CString,CStringA,CStringWおよびLPTSTR,LPWSTR,LPSTR,LPCTSTR,LPCWSTR,LPCSTRの定義プリプロセッサ | ||
+ | #include "atlbase.h" //同上 | ||
+ | #include "cstringt.h" //CStringTの定義プリプロセッサ | ||
+ | #include <vector> | ||
+ | |||
+ | |||
+ | //_bstr_t型を利用するプリプロセッサ | ||
+ | #include "comutil.h" | ||
+ | #ifdef _DEBUG | ||
+ | #pragma comment(lib, "comsuppwd.lib") | ||
+ | #else | ||
+ | #pragma comment(lib, "comsuppw.lib") | ||
+ | #endif | ||
+ | //_bstr_t | ||
+ | |||
+ | //ICU ucnvプリプロセッサ | ||
+ | #include <unicode/ucnv.h> | ||
+ | #include <unicode/translit.h> | ||
+ | #include <unicode/regex.h> | ||
+ | #ifdef _DEBUG | ||
+ | //#pragma comment(lib, "icudt.lib") | ||
+ | #pragma comment(lib, "icuind.lib")//ICU Transliterate関数を使うために必要なライブラリ 正規表現関数も | ||
+ | #pragma comment(lib, "icuucd.lib")//ICU ucnvを使うために必要なライブラリ | ||
+ | //#pragma comment(lib, "icuiod.lib") | ||
+ | #else | ||
+ | #pragma comment(lib, "icudt.lib") | ||
+ | #pragma comment(lib, "icuind.lib") | ||
+ | #pragma comment(lib, "icuuc.lib") | ||
+ | #pragma comment(lib, "icuio.lib") | ||
+ | #endif | ||
+ | |||
+ | |||
+ | #include "UnicodeConverter.h" | ||
+ | |||
+ | |||
+ | using namespace std; | ||
+ | int getvscprintflen(char* format, ...){ | ||
+ | va_list args; | ||
+ | int len; | ||
+ | |||
+ | //可変長引数をargsに格納。引数formatの次から全てをva_list型のargsへ設定 | ||
+ | //引数文字列ポインタをformatの次に合わせる関数。 | ||
+ | va_start( args, format ); | ||
+ | len = _vscprintf( format, args ); | ||
+ | return len; | ||
+ | } | ||
+ | |||
+ | void getvsprintf(char* str, char* format, ...){ | ||
+ | va_list args; | ||
+ | int len; | ||
+ | |||
+ | va_start( args, format ); | ||
+ | len = _vscprintf( format, args ); | ||
+ | vsprintf_s( str, len + 1, format, args ); | ||
+ | } | ||
+ | int _tmain(int argc, _TCHAR* argv[]) | ||
+ | { | ||
+ | char pcStrInt[]="-8192"; | ||
+ | const char pcStrFloat[]="-3.14"; | ||
+ | int nInteger; | ||
+ | long lLong; | ||
+ | double dDouble; | ||
+ | char* pcStrNumeric; | ||
+ | |||
+ | int nLen; | ||
+ | nInteger = atoi(pcStrFloat); | ||
+ | lLong = atol(pcStrFloat); | ||
+ | dDouble = atof(pcStrInt); | ||
+ | |||
+ | printf("★文字列の数値化 型違いの場合\n"); | ||
+ | printf("nInteger->%d\n",nInteger); | ||
+ | printf("lLong ->%d\n",lLong); | ||
+ | printf("dDouble ->%f\n",dDouble); | ||
+ | printf("\n"); | ||
+ | |||
+ | nInteger = atoi(pcStrInt); | ||
+ | lLong = atol(pcStrInt); | ||
+ | dDouble = atof(pcStrFloat); | ||
+ | |||
+ | printf("★文字列の数値化 型一致の場合\n"); | ||
+ | printf("nInteger->%d\n",nInteger); | ||
+ | printf("lLong ->%d\n",lLong); | ||
+ | printf("dDouble ->%f\n",dDouble); | ||
+ | printf("\n"); | ||
+ | |||
+ | |||
+ | //文字列長を取得する | ||
+ | nLen = getvscprintflen("%3.2f", dDouble ); | ||
+ | |||
+ | pcStrNumeric = new char[nLen + 1]; | ||
+ | |||
+ | //文字列を出力※同じ引数を2回与えているのは冗長なので | ||
+ | //pcStrNumericをメンバ関数にしたクラスを作ると一度にまとめれる。 | ||
+ | getvsprintf( pcStrNumeric, "%3.2f", dDouble ); | ||
+ | |||
+ | printf("★数値を文字列 vsprintf関数を利用する場合\n"); | ||
+ | printf( "%s\n", pcStrNumeric); | ||
+ | |||
+ | delete[] pcStrNumeric; | ||
+ | return 0; | ||
+ | } | ||
+ | </syntaxhighlight2> | ||
+ | 出力結果 | ||
+ | <syntaxhighlight2 lang="text"> | ||
+ | ★文字列の数値化 型違いの場合 | ||
+ | nInteger->-3 | ||
+ | lLong ->-3 | ||
+ | dDouble ->-8192.000000 | ||
+ | |||
+ | ★文字列の数値化 型一致の場合 | ||
+ | nInteger->-8192 | ||
+ | lLong ->-8192 | ||
+ | dDouble ->-3.140000 | ||
+ | |||
+ | ★数値を文字列 vsprintf関数を利用する場合 | ||
+ | -3.14 | ||
+ | </syntaxhighlight2> | ||
+ | |||
+ | =='''文字列と日付・日時・時間の変換'''== | ||
+ | 先述の数値の問題と同様、日付・日時・時間も文字列として与えられる場合があり、時制を扱う型との相互変換を行う技術も必要になります。 | ||
+ | |||
+ | |||
+ | 時間処理については、また別の場所で考えたいと思いますが、自分が思うところによると、時間処理には、カレンダー日付を伴う日時の概念と、カレンダー日付を考慮しない、時間の概念の2つがあると思います。時間だけの概念ならば24時間を超えて、1週間=168時間、そして1年=8760時間(うるう年の1年は8784時間ですが…)という具合に表現できると思います。この時間の概念に24時間ごとに1日と数える方式として、1.5日(一日半)にあたる36時間だと「1日と12時間」という表現です。日にちを小数点で表すのは、あまり便利ではありませんが、概念としては存在していて、日付単位にすることもありますし、会話の中では具体的な時間を0.5日割り算として、余りを切り捨てる方式が使われると思います。さらには7日毎(168時間)に1週間として表し、「1週間と1日と12時間」の表現や時間を切り捨てる方式や、日付部分を1.5日と表現する方法。そして、ここから先はうるう年や月あたりに日数の関係であいまいな表現になりますが31日or30日で1カ月と表現する方式として「(およそ)1か月と23日」のような表現に365日毎に1年とした「(およそ)1年と(およそ)3カ月と1週間と2日と10時間」のような表現。大きな単位だけを採用して、小さいものを切り捨てるという概念。ここまでは時間についてでしたが更に細かいところでは時間と分と秒でも表現できて、1時間は60分ですが1時間以上の領域も分で表現し続ける方式として、2時間を120分、24時間を1440分と表すこともあります。1週間を超えるところまで分で表すと10080分でこの先も分で表すケースは人間の感覚による理解を超える表現になってくると思います。同じことを秒でも実施して、1分は60秒の領域を超えて1時間を3600秒そして1日は86400秒。秒の場合は1時間から2時間を超えたあたりで、秒での表現の感覚理解の限界を感じます。ここまでに述べた大きな単位と組み合わせて使う場合には分や秒は59分や59秒といった範囲以内で利用されます。長くなりましたが、こういったものがカレンダー日付を考慮しない時間という概念になると思います。1年や1カ月がどこの1か月か特定されないのが日常の1年や1カ月という表現になりますので、このあたりの表現は人間にわかりやすく説明するあいまいな表現としてだけ存在すると考えていいと思います。 | ||
+ | |||
+ | |||
+ | 上記のカレンダー日付を考慮しない時間に加えて、カレンダー日付を考慮した時間の概念が存在し、これらを短い言葉で表現するなら非暦時間、暦時間と表したいと思います。暦時間の差分を考えることで非暦時間がうまれ、暦時間と非暦時間を結合させる場合には、かならず加減算して、暦時間に変化するということになります。計算機の暦時間の概念は、定義された基準時間を起点に秒単位で管理されていること、その起点が1970年1月1日00時00分00秒となっていて、世界協定時刻UTCとよばれる表現で表されていると理解しておくと良いです。そして、時刻をカウントする変数のbit数が32bitなら2038年までカウントできて、64bitなら3000億年までカウントできる仕組みです。これは個人的な希望になりますが、これからプログラムをする人は64bitの時間変数を扱って欲しいです。作成するプログラムが経済活動や、生活の基盤、生命活動を支えるものであれば尚更です。2038年は、執筆時点からあと24年でやってくるのです。経済的な損失、人的被害、労力を生まないために。各種コンパイラ提供元はそろそろ32bit時間変数のコンパイルをワーニングや使用宣言未定義エラーとかにする工夫を実施しても良いと思うのです。 | ||
+ | |||
+ | |||
+ | これが時間処理の全般になると思います。この暦時間と非暦時間の特殊ケースとして1秒よりも小さい時間であるミリ秒の存在があるといったところでしょうか?そして、文字列として時間を表現する場合には国際社会を含めたルールに基づいて出力します。まずは標準時間からの差が最も重要な概念になります。日本なら+9時間です。あまり日本では関係の無い概念ですがサマータイムという表現もあります。グローバルな展開をするプログラムなら重要な概念かもしれません。相手の時間を思いやる必要のある双方向通信アプリとかなら、なおさら重要です。そして、曜日、午前、午後、24時間表現、表現習慣も国、地域、組織、個人によって異なります。ここでは、日付処理は別の場で考えるとして、システム時間から得られた時刻を文字列にする方法、網羅はできないですが、時刻文字列をシステム時間変数に設定し、歴時間変数として扱う方法について確認したいと思います。この日付の表現に関しても、文字コード変換でお世話になったICUはかなり手広くサポートしています。国際的な文字の変換処理に関する部分の処理系を強くしていっている印象です。たしかに個人では抱えきれないほど国際的な表現は複雑ですので、特化した組織があるというのは、ありがたいことです。 | ||
+ | |||
+ | <syntaxhighlight2 lang="cpp" line start="1"> | ||
+ | #pragma once | ||
+ | #include "stdafx.h" | ||
+ | #include <stdlib.h> | ||
+ | #include <string> //std::string型定義 | ||
+ | #include <mbstring.h> //mbs***関数 | ||
+ | #include <iostream> //cpp cout etc 一般入出力関数 | ||
+ | #include <locale> //Locale関数 | ||
+ | #include <tchar.h> //TCHAR型+_tcs***関数 | ||
+ | #include "atlstr.h" //CString,CStringA,CStringWおよびLPTSTR,LPWSTR,LPSTR,LPCTSTR,LPCWSTR,LPCSTRの定義プリプロセッサ | ||
+ | #include "atlbase.h" //同上 | ||
+ | #include "cstringt.h" //CStringTの定義プリプロセッサ | ||
+ | #include <vector> | ||
+ | |||
+ | |||
+ | //_bstr_t型を利用するプリプロセッサ | ||
+ | #include "comutil.h" | ||
+ | #ifdef _DEBUG | ||
+ | #pragma comment(lib, "comsuppwd.lib") | ||
+ | #else | ||
+ | #pragma comment(lib, "comsuppw.lib") | ||
+ | #endif | ||
+ | //_bstr_t | ||
+ | |||
+ | //ICU ucnvプリプロセッサ | ||
+ | #include <unicode/ucnv.h> | ||
+ | #include <unicode/translit.h> | ||
+ | #include <unicode/regex.h> | ||
+ | #ifdef _DEBUG | ||
+ | //#pragma comment(lib, "icudt.lib") | ||
+ | #pragma comment(lib, "icuind.lib")//ICU Transliterate関数を使うために必要なライブラリ 正規表現関数も | ||
+ | #pragma comment(lib, "icuucd.lib")//ICU ucnvを使うために必要なライブラリ | ||
+ | //#pragma comment(lib, "icuiod.lib") | ||
+ | #else | ||
+ | #pragma comment(lib, "icudt.lib") | ||
+ | #pragma comment(lib, "icuind.lib") | ||
+ | #pragma comment(lib, "icuuc.lib") | ||
+ | #pragma comment(lib, "icuio.lib") | ||
+ | #endif | ||
+ | |||
+ | |||
+ | #include "UnicodeConverter.h" | ||
+ | |||
+ | |||
+ | using namespace std; | ||
+ | int _tmain(int argc, _TCHAR* argv[]) | ||
+ | { | ||
+ | //_tsetlocale(LC_ALL, _T("Japanese")); ロケールセットすると_l関数でロケール指定しなくても日本語が使われます。 | ||
+ | |||
+ | _locale_t localeJpanease; | ||
+ | localeJpanease = _create_locale(LC_ALL, "Japanese"); | ||
+ | |||
+ | //日付や時刻を取り込む文字列の長さは大きくないため、一時的な文字列確保はこのような固定長の配列で問題はないと思います。 | ||
+ | //それでも動的に文字列長を決定してメモリを確保したいというプログラムの効率を無視する場合には、自作しなければいけない関数が増えるのかと思います。 | ||
+ | char tmpbuf[128], timebuf[26], ampm[] = "AM"; | ||
+ | time_t ltime; | ||
+ | struct _timeb structtimebTime; | ||
+ | struct tm today, gmt, xmas = { 0, 0, 12, 25, 11, 93 };//秒, 分, 時間, 日, 月(0~11), 年(1900年基準) | ||
+ | errno_t err; | ||
+ | |||
+ | |||
+ | //__timeb64型構造体変数のアドレスを引数とする_ftime64_s関数でtstructに現在時刻を設定。 | ||
+ | _ftime_s( &structtimebTime ); // _ftimeはC4996 | ||
+ | // | ||
+ | |||
+ | //環境変数TZに設定されたタイムゾーンにしたがってグローバル変数_daylight(夏時間設定)、 | ||
+ | //_timezone(秒時差)、_tzname配列(要素1->タイムゾーン名 要素2->夏時間タイムゾーン名)を設定。 | ||
+ | _tzset(); | ||
+ | |||
+ | |||
+ | //strtimeは10文字で現在時刻を引数の文字列変数に格納する関数。 | ||
+ | _strtime_s( tmpbuf, 128 ); | ||
+ | printf( "OS 時間:\t\t\t\t%s\n", tmpbuf ); | ||
+ | //strdateは9文字で現在日付を引数の文字列変数に格納する関数。 | ||
+ | _strdate_s( tmpbuf, 128 ); | ||
+ | printf( "OS 日付:\t\t\t\t%s\n", tmpbuf ); | ||
+ | |||
+ | // Get UNIX-style time and display as number and string. | ||
+ | //time_t型変数のアドレスを引数とするtime関数でltimeに現在日時秒数を協定世界時UTCで設定。 | ||
+ | time( <ime ); | ||
+ | printf( "秒数による日時情報 1970年1月1日基準:\t%ld\n", ltime ); | ||
+ | |||
+ | //ctime_sは第三引数のtime_t型UTC秒数情報から第一引数の文字列ポインタへ現在のシステムのタイムゾーン時刻生成する関数。 | ||
+ | err = ctime_s(timebuf, 26, <ime); | ||
+ | if (err) | ||
+ | { | ||
+ | printf("ctime_s failed due to an invalid argument."); | ||
+ | exit(1); | ||
+ | } | ||
+ | printf( "現在日時情報 曜日月(英語):\t\t%s", timebuf ); | ||
+ | |||
+ | |||
+ | //_gmtime64_s関数は第一引数のtm型構造体に第二引数で取得したUTC秒数情報からグリニッジ平均時Greenwich Mean Timeすなわち協定世界時を生成する関数。 | ||
+ | //※GMTが天体観測によって管理される時間で1秒の長さが微変動するもの、UTCは原子時計でGMTの情報をもとにうるう秒を入れたりして調整が入る。 | ||
+ | err = _gmtime64_s( &gmt, <ime ); | ||
+ | if (err) | ||
+ | { | ||
+ | printf("_gmtime64_s failed due to an invalid argument."); | ||
+ | } | ||
+ | //asctime_sは第三引数のtm型構造体に格納された情報から第一引数の文字列ポインタへ生成する関数。 | ||
+ | err = asctime_s(timebuf, 26, &gmt); | ||
+ | if (err) | ||
+ | { | ||
+ | printf("asctime_s failed due to an invalid argument."); | ||
+ | exit(1); | ||
+ | } | ||
+ | printf( "協定世界時 UTC:\t\t\t\t%s", timebuf ); | ||
+ | |||
+ | //_localtime64_sはtime_t型UTC秒数情報から第一引数のtm型構造体に現在のタイムゾーンの時刻を設定する関数。 | ||
+ | err = _localtime64_s( &today, <ime ); | ||
+ | if (err) | ||
+ | { | ||
+ | printf("_localtime64_s failed due to an invalid argument."); | ||
+ | exit(1); | ||
+ | } | ||
+ | //tm構造体のtoday変数の24時間形式を格納するメンバ変数tm_hourの値が12以上なら午後なので、午前午後情報格納文字列の内容をPMに。 | ||
+ | if( today.tm_hour >= 12 ) | ||
+ | { | ||
+ | strcpy_s( ampm, sizeof(ampm), "PM" ); | ||
+ | today.tm_hour -= 12;//午後で表現するので、12を引いた。但し、この後tm構造体変数として違う関数への引数とかにすると時間が12時間前になるので用途に注意。 | ||
+ | } | ||
+ | |||
+ | err = asctime_s(timebuf, 26, &today); | ||
+ | if (err) | ||
+ | { | ||
+ | printf("asctime_s failed due to an invalid argument."); | ||
+ | exit(1); | ||
+ | } | ||
+ | |||
+ | //timebufの12文字目から8文字が時間なので、その部分だけを出力し、ampmの情報を付加する。 | ||
+ | printf( "12時間表記 時間:\t\t\t%.8s %s\n", timebuf + 11, ampm); | ||
+ | |||
+ | |||
+ | //_timeb64構造体に取得したタイムゾーン現在時刻のメンバ変数出力 | ||
+ | printf( "現在時刻のミリ秒:\t\t\t%03u[ミリ秒]\n", structtimebTime.millitm ); | ||
+ | printf( "協定世界時とタイムゾーン時刻の差:\t%d\n", structtimebTime.timezone / 60 ); | ||
+ | |||
+ | size_t* pReturnValue = new size_t; | ||
+ | int index = structtimebTime.dstflag; | ||
+ | |||
+ | //タイムゾーン名の文字列長をpReturnValueに取得 | ||
+ | _get_tzname(pReturnValue, NULL, 0, index); | ||
+ | |||
+ | char* timeZoneName = new char[*pReturnValue + 1]; | ||
+ | size_t sizeInBytes = *pReturnValue + 1; | ||
+ | |||
+ | //タイムゾーン名の取得 | ||
+ | _get_tzname(pReturnValue, timeZoneName, sizeInBytes, index); | ||
+ | |||
+ | printf( "タイムゾーン名:\t\t\t\t%s\n", timeZoneName ); | ||
+ | printf( "タイムゾーン名文字数:\t\t\t%d[byte]\n", *pReturnValue ); | ||
+ | printf( "夏時間適用フラグ:\t\t\t%s\n", structtimebTime.dstflag ? "夏時間" : "夏時間非適用" ); | ||
+ | |||
+ | //mktime関数は初期値が与えられているtm型構造体の情報から日時情報を生成し、他のメンバ変数の設定を行う関数 | ||
+ | if(mktime(&xmas) != (time_t)-1) | ||
+ | { | ||
+ | err = asctime_s(timebuf, 26, &xmas); | ||
+ | if (err) | ||
+ | { | ||
+ | printf("asctime_s failed due to an invalid argument."); | ||
+ | exit(1); | ||
+ | } | ||
+ | printf( "指定日付\t\t\t\t%s\n", timebuf ); | ||
+ | } | ||
+ | |||
+ | err = _localtime64_s( &today, <ime ); | ||
+ | if (err) | ||
+ | { | ||
+ | printf(" _localtime64_s failed due to invalid arguments."); | ||
+ | exit(1); | ||
+ | } | ||
+ | |||
+ | //★時間変数を文字列に変換する関数 strftime | ||
+ | *pReturnValue = strftime( tmpbuf, 128, "Today is %A, day %d of %B in the year %Y.\n", &today ); | ||
+ | printf("%d[byte]\n",* pReturnValue); | ||
+ | //英語表記の曜日、月名が取得できる。 | ||
+ | strftime( tmpbuf, 128, "Today is %A, day %d of %B in the year %Y.\n", &today ); | ||
+ | printf( tmpbuf ); | ||
+ | |||
+ | *pReturnValue = _strftime_l(tmpbuf, 128, "今日は(%y年)%Y年%B(%b月)%d日(%A:%a;%w番目の曜日 %W回目の%A) %U週目 %j日目 現在時刻は(%p %I)%H:%M:%S\n", &today, localeJpanease ); | ||
+ | printf("%d[byte]\n",* pReturnValue); | ||
+ | //ロケール設定により日本語表記の曜日、月名が取得できる。 | ||
+ | _strftime_l(tmpbuf, 128, "今日は(%y年)%Y年%B(%b月)%d日(%A:%a;%w番目の曜日 %W回目の%A) %U週目 %j日目 現在時刻は(%p %I)%H:%M:%S\n", &today, localeJpanease ); | ||
+ | printf( tmpbuf ); | ||
+ | |||
+ | *pReturnValue = _strftime_l(tmpbuf, 128, "%#c,%#x,%%,%#S,%#a,%#%,%z,%Z\n", &today, localeJpanease ); | ||
+ | printf("%d[byte]\n",* pReturnValue); | ||
+ | //ロケール設定により日本語表記の曜日、月名が取得できる。 | ||
+ | _strftime_l(tmpbuf, 128, "%#c,%#x,%%,%#S,%#a,%#%,%z,%Z\n", &today, localeJpanease ); | ||
+ | printf( tmpbuf ); | ||
+ | return 0; | ||
+ | } | ||
+ | </syntaxhighlight2> | ||
+ | |||
+ | |||
+ | 出力結果 | ||
+ | OS 時間: 20:18:03 | ||
+ | OS 日付: 10/13/14 | ||
+ | 秒数による日時情報 1970年1月1日基準: 1413199083 | ||
+ | 現在日時情報 曜日月(英語): Mon Oct 13 20:18:03 2014 | ||
+ | 協定世界時 UTC: Mon Oct 13 11:18:03 2014 | ||
+ | 12時間表記 時間: 08:18:03 PM | ||
+ | 現在時刻のミリ秒: 006[ミリ秒] | ||
+ | 協定世界時とタイムゾーン時刻の差: -9 | ||
+ | タイムゾーン名: 東京 (標準時) | ||
+ | タイムゾーン名文字数: 14[byte] | ||
+ | 夏時間適用フラグ: 夏時間非適用 | ||
+ | 指定日付 Sat Dec 25 12:00:00 1993 | ||
+ | |||
+ | 53[byte] | ||
+ | Today is Monday, day 13 of October in the year 2014. | ||
+ | 80[byte] | ||
+ | 今日は(14年)2014年10月(10月)13日(月曜日:月;1番目の曜日 41回目の月曜日) 41週目 286日目 現在時刻は(午後 08)20:18:03 | ||
+ | 59[byte] | ||
+ | 2014年10月13日 20:18:03,2014年10月13日,,3,月,,東京 (標準時),東京 (標準時) | ||
+ | |||
+ | と上記のように時間の表記を文字列に変換できます。ICUによる変換は時間があれば、サンプルを作成したいと思います。 | ||
+ | |||
+ | |||
+ | それでICUによる時間の文字列化ですが、 | ||
+ | サンプルは以下にしめすような感じです。UCalendarというクラスとCalendar+SimpleFormatクラスの2通りがありまして、UCalendarの方はちょっと使いにくそうでした。あとは、タイムゾーンの対応がものすごくて、びっくりします。言語別にUnicodeで表記が出来ます。でも言語別を指定するためのキーワードを知るのが大変で、カレンダーのロケールについては、詳細な一覧方法は提供されていないようにも思います。オーソドックスなロケールは一覧できますが、これでは不十分でして、一番詳しいのは、英語のページになりますが、http://www.unicode.org/reports/tr35/ のサイトになります。長すぎる。日本語のロケールについては、"ja","ja-JP"の基本的な二つに加えてカレンダー用のロケールとして"ja_JP_TRADITIONAL","ja_JP@calendar=japanese"があり、こちらのロケールを使うと公年号(645年の大化から始まって明治 大正 昭和 平成)を使った表現に対応できます。他にも"ja"と同じですが、"japanese"や"jpn"でも良さそうでした。jpnはISO3表記ってことになるのでしょうか?難しいです。これが世界684の地域と620のタイムゾーンにわたって定義されているのでしょうから、なんつうか、やっぱ戦争でもして世界征服して一つの国になったほうがよかったんじゃないのかって思うくらい言語は分かれています。いや冗談冗談。戦争は駄目ですよ。不謹慎な冗談はやめた方がいいか…何の得にもならんしね。こうやって、全く面白くもないのに、おもしろいとおもって書いたことをつつかれて、社会的に抹殺されていくんだろうなぁ。有名人は大変だねぇ。あり得ない発言はだめなんですもんね。わけわからんことを言うと影響力ありますからね。そりゃ世間から指摘されますよね。全く思ってもないようなことを言うのだめだわな。 | ||
+ | |||
+ | |||
+ | まずは、UCalendarを使ったサンプル。 | ||
+ | <syntaxhighlight2 lang="cpp" line start="1"> | ||
+ | #pragma once | ||
+ | #include "stdafx.h" | ||
+ | #include <stdlib.h> | ||
+ | #include <string> //std::string型定義 | ||
+ | #include <mbstring.h> //mbs***関数 | ||
+ | #include <iostream> //cpp cout etc 一般入出力関数 | ||
+ | #include <locale> //Locale関数 | ||
+ | #include <tchar.h> //TCHAR型+_tcs***関数 | ||
+ | #include "atlstr.h" //CString,CStringA,CStringWおよびLPTSTR,LPWSTR,LPSTR,LPCTSTR,LPCWSTR,LPCSTRの定義プリプロセッサ | ||
+ | #include "atlbase.h" //同上 | ||
+ | #include "cstringt.h" //CStringTの定義プリプロセッサ | ||
+ | #include <vector> //Vector型テンプレートクラス | ||
+ | |||
+ | #include <sys/timeb.h> //Timeb型構造体 | ||
+ | |||
+ | //_bstr_t型を利用するプリプロセッサ(ライブラリはデバッグモードとリリースモード個別設定) | ||
+ | #include "comutil.h" | ||
+ | |||
+ | #ifdef _DEBUG | ||
+ | #pragma comment(lib, "comsuppwd.lib") | ||
+ | #else | ||
+ | #pragma comment(lib, "comsuppw.lib") | ||
+ | #endif | ||
+ | //_bstr_t _End | ||
+ | |||
+ | //ICU ucnvプリプロセッサ(ライブラリはデバッグモードとリリースモード個別設定) | ||
+ | #include <unicode/ucnv.h> //ucnv文字コード変換ライブラリヘッダ | ||
+ | #include <unicode/translit.h> //文字変換ライブラリヘッダ | ||
+ | #include <unicode/regex.h> //正規表現 | ||
+ | #include <unicode/ucsdet.h> //文字コード判定 | ||
+ | #include <unicode/ucal.h> //文字コード判定 | ||
+ | #include <unicode/uclean.h> //u_cleanup関数 | ||
+ | /* for uloc_getDefault() */ | ||
+ | #include <unicode/uloc.h> | ||
+ | #include <unicode/calendar.h> | ||
+ | #include <unicode/smpdtfmt.h> | ||
+ | |||
+ | //#include "unicode/utypes.h" | ||
+ | //#include "unicode/locid.h" | ||
+ | //#include "unicode/unistr.h" | ||
+ | //#include "unicode/tzfmt.h" | ||
+ | //#include "unicode/tznames.h" | ||
+ | |||
+ | |||
+ | #ifdef _DEBUG | ||
+ | #pragma comment(lib, "icudt.lib") | ||
+ | #pragma comment(lib, "icuucd.lib") //ICU ucnvを使うために必要なライブラリ | ||
+ | #pragma comment(lib, "icuind.lib") //ICU Transliterate関数を使うために必要なライブラリ 正規表現関数も | ||
+ | #pragma comment(lib, "iculed.lib") | ||
+ | #pragma comment(lib, "iculxd.lib") | ||
+ | #pragma comment(lib, "icuiod.lib") | ||
+ | #pragma comment(lib, "icutud.lib") | ||
+ | |||
+ | #else | ||
+ | //#pragma comment(lib, "icudt.lib") | ||
+ | #pragma comment(lib, "icuind.lib") //ICU Transliterate関数を使うために必要なライブラリ 正規表現関数も | ||
+ | #pragma comment(lib, "icuuc.lib") //ICU ucnvを使うために必要なライブラリ | ||
+ | //#pragma comment(lib, "icuio.lib") | ||
+ | #endif | ||
+ | //Data Library icudtXX(d).dll icudt(d).lib | ||
+ | //Common Library icuucXX(d).dll icuuc(d).lib | ||
+ | //Internationalization(i18n) Library icuinXX(d).dll icuin(d).lib | ||
+ | //Layout Engine iculeXX(d).dll icule(d).lib | ||
+ | //Layout Extention Engine iculxXX(d).dll iculx(d).lib | ||
+ | //ICU I/O(Unicode stdio) Library icuioXX(d).dll icuio(d).lib | ||
+ | //Tool Utility Library icutuXX(d).dll icutu(d).lib | ||
+ | |||
+ | //ICU ucnv _End | ||
+ | |||
+ | #include "UnicodeConverter.h" | ||
+ | |||
+ | using namespace std; | ||
+ | |||
+ | int _tmain(int argc, _TCHAR* argv[]) | ||
+ | { | ||
+ | _tsetlocale(LC_ALL, _T("Japanese")); //ロケールセットすると_l関数でロケール指定しなくても日本語が使われます。 | ||
+ | |||
+ | _locale_t localeJpanease; | ||
+ | localeJpanease = _create_locale(LC_ALL, "Japanese"); | ||
+ | |||
+ | int32_t int32TimeZoneID; | ||
+ | UChar* pucharResult = new UChar[1024]; | ||
+ | |||
+ | UErrorCode err = U_ZERO_ERROR; | ||
+ | printf("%s\n",uloc_getDefault()); | ||
+ | UCalendar* cal = ucal_open( | ||
+ | L"Asia/Tokyo", 10, //TimezoneID と文字数 | ||
+ | uloc_getDefault(), //Locale名 "ja_JP" | ||
+ | UCAL_TRADITIONAL, //カレンダータイプ | ||
+ | &err); | ||
+ | printf("errorNum?->%d\n",err); | ||
+ | if (!cal) | ||
+ | { | ||
+ | err = U_ZERO_ERROR; | ||
+ | fprintf(stderr, "ICU error: %s\n", u_errorName(err)); | ||
+ | u_cleanup(); | ||
+ | return ; | ||
+ | } | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | //★ここからしばらくは日付表示とは関係の無い、余計なプログラム | ||
+ | |||
+ | //属性値取得関数 最初の曜日の番号は1 | ||
+ | printf("★現在のオープンしているZoneIDの各種属性値を取得する関数。\n"); | ||
+ | printf("Attrbute->%d\n", ucal_getAttribute(cal, UCAL_FIRST_DAY_OF_WEEK)); | ||
+ | printf("\n"); | ||
+ | |||
+ | |||
+ | //ゾーンIDを取得する関数。もちろんAsia/Tokyo。 | ||
+ | printf("★現在のオープンしているZoneIDのTimeZoneIDをUchar型変数に取得し、その文字数を返す関数\n"); | ||
+ | err = U_ZERO_ERROR; | ||
+ | int32TimeZoneID = ucal_getTimeZoneID(cal, pucharResult, 1024, &err); | ||
+ | wprintf(L"TimezoneID->%d[Byte]:%s\n",int32TimeZoneID,pucharResult);//10:Asia/Tokyo | ||
+ | printf("\n"); | ||
+ | |||
+ | |||
+ | //タイプによるロケール名を取得。 | ||
+ | //ULOC_ACTUAL_LOCALE->ja | ||
+ | //ULOC_VALID_LOCALE->ja_JP | ||
+ | //ULOC_REQUESTED_LOCALE->NULL | ||
+ | printf("★現在のオープンしているZoneIDのULocDataLocaleTypeによる名前を取得。\n"); | ||
+ | err = U_ZERO_ERROR; | ||
+ | printf("TypeLocale->%s\n", ucal_getLocaleByType(cal, ULOC_VALID_LOCALE, &err)); | ||
+ | printf("\n"); | ||
+ | |||
+ | //★ここまでが、かなり余計なプログラムでした。 | ||
+ | //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ | ||
+ | |||
+ | //日付をセットする。 | ||
+ | err = U_ZERO_ERROR; | ||
+ | ucal_setDateTime(cal, 2014, UCAL_OCTOBER, 17, 22, 45, 00, &err);//直接指定。 | ||
+ | ucal_setMillis(cal, ucal_getNow(), &err);//現在日時での指定で上書き。ミリ秒単位で表現されるダブル型の数値。 | ||
+ | //関数名がミリ秒だけを扱うみたいに見えるけど、これで日付時刻ミリ秒まで全部セットされる。 | ||
+ | |||
+ | |||
+ | |||
+ | //特定のフィールドの制限値取得 月の最大。11でした。年の最大は144683です。14万年… | ||
+ | printf("★現在のオープンしているZoneIDの各種フィールド制限値の取得関数\n"); | ||
+ | int32_t int32TempLimitValue; | ||
+ | err = U_ZERO_ERROR; | ||
+ | int32TempLimitValue = ucal_getLimit(cal,UCAL_MILLISECOND,UCAL_MINIMUM, &err); | ||
+ | printf("Limit->%d\n",int32TempLimitValue); | ||
+ | printf("\n"); | ||
+ | |||
+ | //特定のフィールドのロール 時間を追加したりできる。3週間追加する例。コメント化してますけど。 | ||
+ | printf("★現在のオープンしているZoneIDの各種フィールドロール関数\n"); | ||
+ | int32_t int32Amount = 3; | ||
+ | err = U_ZERO_ERROR; | ||
+ | //ucal_roll(cal, UCAL_WEEK_OF_YEAR, int32Amount,&err); | ||
+ | printf("Limit->%d\n",int32Amount); | ||
+ | printf("\n"); | ||
+ | |||
+ | err = U_ZERO_ERROR; | ||
+ | UDate udateGetMillis; | ||
+ | err = U_ZERO_ERROR; | ||
+ | udateGetMillis = ucal_getMillis(cal, &err); | ||
+ | printf("★現在のオープンしているZoneIDのミリ秒を取得。\n"); | ||
+ | err = U_ZERO_ERROR; | ||
+ | printf("GetMilli->%f %f %f\n", udateGetMillis , ucal_getNow(), ucal_getGregorianChange(cal, &err)); | ||
+ | printf("\n"); | ||
+ | |||
+ | //日時の出力 | ||
+ | printf("Date->%d/%d/%d\n", | ||
+ | ucal_get(cal, UCAL_YEAR, &err), | ||
+ | ucal_get(cal, UCAL_MONTH, &err) + 1, | ||
+ | ucal_get(cal, UCAL_DATE, &err)); | ||
+ | |||
+ | printf("Time->%d:%d:%d:%d\n", | ||
+ | ucal_get(cal, UCAL_HOUR_OF_DAY, &err), | ||
+ | ucal_get(cal, UCAL_MINUTE, &err) + 1, | ||
+ | ucal_get(cal, UCAL_SECOND, &err), | ||
+ | ucal_get(cal, UCAL_MILLISECOND, &err)); | ||
+ | |||
+ | printf("Othr->%d:%d:%d:%d\n", | ||
+ | ucal_get(cal, UCAL_DAY_OF_WEEK, &err), | ||
+ | ucal_get(cal, UCAL_AM_PM, &err) , | ||
+ | ucal_get(cal, UCAL_ZONE_OFFSET, &err), | ||
+ | ucal_get(cal, UCAL_DST_OFFSET, &err)); | ||
+ | |||
+ | ucal_close(cal); | ||
+ | u_cleanup(); | ||
+ | return 0; | ||
+ | } | ||
+ | </syntaxhighlight2> | ||
+ | 出力 大体こんな感じ | ||
+ | <syntaxhighlight2 lang="text"> | ||
+ | ★現在のオープンしているZoneIDの各種属性値を取得する関数。 | ||
+ | Attrbute->1 | ||
+ | |||
+ | ★現在のオープンしているZoneIDのTimeZoneIDをUchar型変数に取得し、その文字数を返す関数 | ||
+ | TimezoneID->10[Byte]:Asia/Tokyo | ||
+ | |||
+ | ★現在のオープンしているZoneIDのULocDataLocaleTypeによる名前を取得。 | ||
+ | TypeLocale->ja_JP | ||
+ | |||
+ | ★現在のオープンしているZoneIDの各種フィールド制限値の取得関数 | ||
+ | Limit->0 | ||
+ | |||
+ | ★現在のオープンしているZoneIDの各種フィールドロール関数 | ||
+ | Limit->3 | ||
+ | |||
+ | ★現在のオープンしているZoneIDのミリ秒を取得。 | ||
+ | GetMilli->1413654266519.000000 1413654266529.000000 -12219292800000.000000 | ||
+ | |||
+ | Date->2014/10/19 | ||
+ | Time->2:45:26:519 | ||
+ | Othr->1:0:32400000:0 | ||
+ | </syntaxhighlight2> | ||
+ | そして、Calendar+SimpleFormatクラスを使うサンプルは以下のような感じ。上記のプログラムの続きなので、インクルードとか飛ばします。 | ||
+ | <syntaxhighlight2 lang="cpp" line start="1"> | ||
+ | UErrorCode status = U_ZERO_ERROR; | ||
+ | //Calendar *cals = Calendar::createInstance(status);//日本語カレンダーロケールは ja_JP@calendar=japanese ja_JP_TRADITIONAL ja_JP ja japaneseが指定可能 | ||
+ | Calendar *cals = Calendar::createInstance("ja_JP@calendar=japanese", status); | ||
+ | SimpleDateFormat *fmt = new SimpleDateFormat(UnicodeString("SSS S U Q q W w e F D zzzz zzz zz z EEE EE E YYYY YYY YY Y yyyy yyy yy v GG G y.M.d vv HH:mm:ss vvvv K:mm a vvv hh:mm h:m KK:mm H:m aaa yyyyy.MM.dd GGG"), status); | ||
+ | //SimpleDateFormat ★ja_JP(引数無し) ☆ja_JP_TRADITIONAL 1988年基準 年引数が1なら1989年で公元号1年 公元号名は表示されない。 | ||
+ | //z タイムゾーン名(★GMT+09:18:59 ☆JST) | ||
+ | //zz タイムゾーン (★GMT+09:18:59 ☆JST) | ||
+ | //zzz タイムゾーン (★GMT+09:18:59 ☆JST) | ||
+ | //zzzz タイムゾーン年-タイムゾーン名(★2014-GMT+09:18:59 ☆2014-日本標準時) | ||
+ | //v タイムゾーン年-タイムゾーン名(★2014-日本時間 ☆2014-JST) | ||
+ | //vv タイムゾーン (★表記無し) | ||
+ | //vvv タイムゾーン (★表記無し) | ||
+ | //vvvv タイムゾーン名(★日本時間 ☆日本標準時) | ||
+ | //G グレゴリオ暦年-歴名(★2014-西暦 ☆平成) | ||
+ | //GG グレゴリオ暦名(年数値無し★西暦 ☆平成) | ||
+ | //GGG グレゴリオ暦名(年数値無し★西暦 ☆平成) | ||
+ | //YYYY グレゴリオ暦年-公元号年(★2014-0026 ☆2014-2014) | ||
+ | //YYY 公元号年orグレゴリオ暦年(3桁表現最小表現 0埋め★026 ☆2014) | ||
+ | //YY 公元号年orグレゴリオ暦年(2桁表現固定0埋め★26 ☆14) | ||
+ | //Y 公元号年orグレゴリオ暦年(最小文字列★26 ☆2014) | ||
+ | //yyyyy公元号年5桁数値のみ(0埋め) | ||
+ | //yyyy 公元号年4桁数値のみ(0埋め) | ||
+ | //yyy 公元号年3桁数値のみ(0埋め) | ||
+ | //yy 公元号年2桁数値のみ(0埋め) | ||
+ | //y 公元号年数値のみ | ||
+ | //M 数値表現の月(最小文字列)※小文字だと時間の分 | ||
+ | //MM 数値表現の月(2桁表現)※小文字だと時間の分 | ||
+ | //MMMMM数値表現の月(最小文字列)※小文字だと時間の分 | ||
+ | //d 数値表現の日(最小文字列) | ||
+ | //dd 数値表現の日(2桁表現) | ||
+ | //EEE 曜日(★土 1日前の曜日 ☆日) | ||
+ | //EE 曜日(★土 1日前の曜日 ☆日) | ||
+ | //E 曜日(★土 1日前の曜日 ☆日) | ||
+ | //a 午前・午後表記(漢字日本語★午前) | ||
+ | //K 数値表現の時間(0時は0のまま 最小文字列) | ||
+ | //KK 数値表現の時間(0時は0のまま 2桁表現0埋め) | ||
+ | //H 数値表現の時間(24時間制 0時は0のまま 最小文字列) | ||
+ | //HH 数値表現の時間(24時間制 0時は0のまま 2桁表現0埋め) | ||
+ | //h 数値表現の時間(0時は12時 最小文字列) | ||
+ | //hh 数値表現の時間(0時は12時 2桁表現0埋め) | ||
+ | //m 数値用言の分(最小文字列)※大文字だと日付の月 | ||
+ | //mm 数値用言の分(2桁表現0埋め)※大文字だと日付の月 | ||
+ | //s 数値表現の秒(最小文字列) | ||
+ | //ss 数値表現の秒(2桁表現0埋め) | ||
+ | //その他 | ||
+ | //S ミリ秒 | ||
+ | //u extended年 | ||
+ | //Q 四半期 テキスト&番号 | ||
+ | //q | ||
+ | //w 週目 通年 | ||
+ | //W 週目 月 | ||
+ | //D 日目 通年 | ||
+ | //e 曜日番号 | ||
+ | //F 何回目の曜日 月 | ||
+ | // | ||
+ | |||
+ | fmt->adoptCalendar(cals);//フォーマットにカレンダーを設定。 | ||
+ | for(int k=2014;k<2015;k++){ | ||
+ | cals->set(k - 1988 , 10 - 1, 17, 14, 0, 0);//カレンダーの日付を数値で設定する方法 ja_JP_TRADITIONAは1988年基準 昭和元年が1989年 | ||
+ | UDate now = cals->getTime(status);//nowに現在時間を取得。UDateはDouble型と同じです。 | ||
+ | UnicodeString buf; | ||
+ | fmt->format(now, buf);//UnicodeString型のbufの内容をnowに設定されている時間を文字列にしたものに変換。変換は指定されているフォーマットの形式。 | ||
+ | char* dst = new char[256]; | ||
+ | std::string conv(buf.extract(0, buf.length(), 0, "shift_jis"), '\0');//string型convをbufの文字列のShiftJIS形式長さ分確保 初期値は\0で埋める | ||
+ | //UnicodeStringのextractはbufの中身を(第一引数 =0)文字目から、(第二引数 =buf.length())文字目までを第四引数にしていされた文字コードの型に変換して第三引数の変数に格納する関数 | ||
+ | //変換先が指定されていない場合でも変換後の文字サイズが返却されます。ここでは文字サイズを取得してconvを初期化しています。 | ||
+ | buf.extract(0, buf.length(), &conv[0], "shift_jis");//ここでconvに実際に変換後の文字を格納。 | ||
+ | memcpy(dst, conv.c_str(), conv.size());//convの内容をchar型dstにコピー | ||
+ | printf("%d-%s ", k, conv.c_str());//convの内容を出力。 | ||
+ | delete dst; | ||
+ | } | ||
+ | delete fmt; | ||
+ | </syntaxhighlight2> | ||
+ | 出力 いろんな種類の出力をがっつり記述したので、わけわからないことになってますが | ||
+ | <syntaxhighlight2 lang="text"> | ||
+ | 2014-274 2 26 4 4 3 42 6 3 290 日本標準時 JST JST JST 金 金 金 2014 2014 14 2014 0026 026 26 JST 平成 平成 26.10.17 14:00:00 日本標準時 2:00 午後 02:00 2:0 02:00 14:0 午後 00026.10.17 平成 | ||
+ | </syntaxhighlight2> | ||
+ | あとのほうのプログラムの方がタイムゾーン名を各国語で表示できる分、国際化には向いているかもしれませんが、そんなプログラム組む人いるのかなぁ。 | ||
+ | ロケール名一覧は後で示す日本語タイムゾーンの各ロケールごとの表示一覧に、タイムゾーン名一覧は各タイムゾーンの日本語表記一覧に記載しました。 | ||
+ | |||
+ | |||
+ | |||
+ | UCalendarクラスやCalendarクラスの使い方はICUのサイトを確認して下さい。なんやかんやで長い記事になっているせいで忘れられているかもしれませんが、ここでは文字列操作に関する情報を中心に扱っています。ちなみにICUのサイトを見てもクラス仕様書がきっちりのっているものの個別の関数の具体的な使い方についてはあまり触れられていません。関数名と機能から、あぁこういう風に使って欲しいんだなっていうのを感じ取るスキルが求められます。なので自分もカレンダーのロケール名指定方法の詳細な一覧は入手できませんでした。もしわかった人がいたら、各自のブログやWikiで情報を発信して下さい。よろしくお願いします。たぶんICUをここまで掘り下げて使っている人はいないはず。上記に記述した各タイムゾーンやロケールの一覧を取得するにはStringEnumerationやUEnumerationクラスの使い方を理解したり、Locale、Timezoneクラスの構造を理解することが求められると思います。頑張ってください。 | ||
+ | |||
+ | |||
+ | それから、年号なんですけどサンプルプログラムのFor文では2014年だけの一回のループになってますが、ちょこっと変えて645年からにすると、まぁ素敵なほどに年号を羅列してくれます。他にも、日本のタイムゾーンが各国でどのように表示されているのか、あるいは、タイムゾーンがどれほどあるのかを一覧した、日本目線の一覧を貼っておきます。ICUは文字列操作の処理範囲をここまで広くかんがえているんだなあと考えさせられます。一種のデータベースと言えるかもしれません。うすっぺらな自分では調べきることは困難な範囲です。日本のことですらあまりわかっていないし… | ||
+ | |||
+ | |||
+ | プログラムでUNICODE文字を出力してますが、コンソール表示のときにはSJISに変換されるため、SJISで表現できない文字は文字化け?というか変換先がないため正しく表示されません。正しく表示させたい場合は先の項目で説明したとおり、ファイル入出力をつかってUNICODE形式でテキストファイルに出力するといいです。Unicode対応のメモ帳で閲覧できます。Terapadは無理。自分は今回の機会にサクラエディタを導入しました。Unicodeも対応している優秀なエディタであることに気付かされました。UNICODEフォントですが、Windows標準のフォントファイルは実はUnicodeフォントになっています。すごいです。 | ||
+ | |||
+ | 年号サンプル <syntaxhighlight2 lang="text"> | ||
+ | 645-大化1:646-大化2:647-大化3:648-大化4:649-大化5:650-白雉1:651-白雉2:652-白雉3:653-白雉4:654-白雉5:655-白雉6:656-白雉7:657-白雉8:658-白雉9:659-白雉10:660-白雉11:661-白雉12:662-白雉13:663-白雉14:664-白雉15:665-白雉16:666-白雉17:667-白雉18:668-白雉19:669-白雉20:670-白雉21:671-白雉22:672-白鳳1:673-白鳳2:674-白鳳3:675-白鳳4:676-白鳳5:677-白鳳6:678-白鳳7:679-白鳳8:680-白鳳9:681-白鳳10:682-白鳳11:683-白鳳12:684-白鳳13:685-白鳳14:686-朱鳥1:687-朱鳥2:688-朱鳥3:689-朱鳥4:690-朱鳥5:691-朱鳥6:692-朱鳥7:693-朱鳥8:694-朱鳥9:695-朱鳥10:696-朱鳥11:697-朱鳥12:698-朱鳥13:699-朱鳥14:700-朱鳥15:701-大宝1:702-大宝2:703-大宝3:704-慶雲1:705-慶雲2:706-慶雲3:707-慶雲4:708-和銅1:709-和銅2:710-和銅3:711-和銅4:712-和銅5:713-和銅6:714-和銅7:715-霊亀1:716-霊亀2:717-霊亀3:718-養老2:719-養老3:720-養老4:721-養老5:722-養老6:723-養老7:724-神亀1:725-神亀2:726-神亀3:727-神亀4:728-神亀5:729-天平1:730-天平2:731-天平3:732-天平4:733-天平5:734-天平6:735-天平7:736-天平8:737-天平9:738-天平10:739-天平11:740-天平12:741-天平13:742-天平14:743-天平15:744-天平16:745-天平17:746-天平18:747-天平19:748-天平20:749-天平勝宝1:750-天平勝宝2:751-天平勝宝3:752-天平勝宝4:753-天平勝宝5:754-天平勝宝6:755-天平勝宝7:756-天平勝宝8:757-天平宝字1:758-天平宝字2:759-天平宝字3:760-天平宝字4:761-天平宝字5:762-天平宝字6:763-天平宝字7:764-天平宝字8:765-天平神護1:766-天平神護2:767-神護景雲1:768-神護景雲2:769-神護景雲3:770-宝亀1:771-宝亀2:772-宝亀3:773-宝亀4:774-宝亀5:775-宝亀6:776-宝亀7:777-宝亀8:778-宝亀9:779-宝亀10:780-宝亀11:781-天応1:782-延暦1:783-延暦2:784-延暦3:785-延暦4:786-延暦5:787-延暦6:788-延暦7:789-延暦8:790-延暦9:791-延暦10:792-延暦11:793-延暦12:794-延暦13:795-延暦14:796-延暦15:797-延暦16:798-延暦17:799-延暦18:800-延暦19:801-延暦20:802-延暦21:803-延暦22:804-延暦23:805-延暦24:806-大同1:807-大同2:808-大同3:809-大同4:810-弘仁1:811-弘仁2:812-弘仁3:813-弘仁4:814-弘仁5:815-弘仁6:816-弘仁7:817-弘仁8:818-弘仁9:819-弘仁10:820-弘仁11:821-弘仁12:822-弘仁13:823-弘仁14:824-天長1:825-天長2:826-天長3:827-天長4:828-天長5:829-天長6:830-天長7:831-天長8:832-天長9:833-天長10:834-承和1:835-承和2:836-承和3:837-承和4:838-承和5:839-承和6:840-承和7:841-承和8:842-承和9:843-承和10:844-承和11:845-承和12:846-承和13:847-承和14:848-嘉祥1:849-嘉祥2:850-嘉祥3:851-仁寿1:852-仁寿2:853-仁寿3:854-仁寿4:855-斉衡2:856-斉衡3:857-天安1:858-天安2:859-貞観1:860-貞観2:861-貞観3:862-貞観4:863-貞観5:864-貞観6:865-貞観7:866-貞観8:867-貞観9:868-貞観10:869-貞観11:870-貞観12:871-貞観13:872-貞観14:873-貞観15:874-貞観16:875-貞観17:876-貞観18:877-元慶1:878-元慶2:879-元慶3:880-元慶4:881-元慶5:882-元慶6:883-元慶7:884-元慶8:885-仁和1:886-仁和2:887-仁和3:888-仁和4:889-寛平1:890-寛平2:891-寛平3:892-寛平4:893-寛平5:894-寛平6:895-寛平7:896-寛平8:897-寛平9:898-昌泰1:899-昌泰2:900-昌泰3:901-延喜1:902-延喜2:903-延喜3:904-延喜4:905-延喜5:906-延喜6:907-延喜7:908-延喜8:909-延喜9:910-延喜10:911-延喜11:912-延喜12:913-延喜13:914-延喜14:915-延喜15:916-延喜16:917-延喜17:918-延喜18:919-延喜19:920-延喜20:921-延喜21:922-延喜22:923-延長1:924-延長2:925-延長3:926-延長4:927-延長5:928-延長6:929-延長7:930-延長8:931-承平1:932-承平2:933-承平3:934-承平4:935-承平5:936-承平6:937-承平7:938-天慶1:939-天慶2:940-天慶3:941-天慶4:942-天慶5:943-天慶6:944-天慶7:945-天慶8:946-天慶9:947-天暦1:948-天暦2:949-天暦3:950-天暦4:951-天暦5:952-天暦6:953-天暦7:954-天暦8:955-天暦9:956-天暦10:957-天暦11:958-天徳2:959-天徳3:960-天徳4:961-応和1:962-応和2:963-応和3:964-康保1:965-康保2:966-康保3:967-康保4:968-安和1:969-安和2:970-天禄1:971-天禄2:972-天禄3:973-天禄4:974-天延2:975-天延3:976-貞元1:977-貞元2:978-貞元3:979-天元2:980-天元3:981-天元4:982-天元5:983-永観1:984-永観2:985-寛和1:986-寛和2:987-永延1:988-永延2:989-永祚1:990-永祚2:991-正暦2:992-正暦3:993-正暦4:994-正暦5:995-長徳1:996-長徳2:997-長徳3:998-長徳4:999-長保1:1000-長保2:1001-長保3:1002-長保4:1003-長保5:1004-寛弘1:1005-寛弘2:1006-寛弘3:1007-寛弘4:1008-寛弘5:1009-寛弘6:1010-寛弘7:1011-寛弘8:1012-寛弘9:1013-長和2:1014-長和3:1015-長和4:1016-長和5:1017-寛仁1:1018-寛仁2:1019-寛仁3:1020-寛仁4:1021-治安1:1022-治安2:1023-治安3:1024-万寿1:1025-万寿2:1026-万寿3:1027-万寿4:1028-長元1:1029-長元2:1030-長元3:1031-長元4:1032-長元5:1033-長元6:1034-長元7:1035-長元8:1036-長元9:1037-長暦1:1038-長暦2:1039-長暦3:1040-長暦4:1041-長久2:1042-長久3:1043-長久4:1044-長久5:1045-寛徳2:1046-永承1:1047-永承2:1048-永承3:1049-永承4:1050-永承5:1051-永承6:1052-永承7:1053-天喜1:1054-天喜2:1055-天喜3:1056-天喜4:1057-天喜5:1058-康平1:1059-康平2:1060-康平3:1061-康平4:1062-康平5:1063-康平6:1064-康平7:1065-治暦1:1066-治暦2:1067-治暦3:1068-治暦4:1069-延久1:1070-延久2:1071-延久3:1072-延久4:1073-延久5:1074-承保1:1075-承保2:1076-承保3:1077-承保4:1078-承暦2:1079-承暦3:1080-承暦4:1081-永保1:1082-永保2:1083-永保3:1084-応徳1:1085-応徳2:1086-応徳3:1087-寛治1:1088-寛治2:1089-寛治3:1090-寛治4:1091-寛治5:1092-寛治6:1093-寛治7:1094-寛治8:1095-嘉保2:1096-嘉保3:1097-永長2:1098-承徳2:1099-康和1:1100-康和2:1101-康和3:1102-康和4:1103-康和5:1104-長治1:1105-長治2:1106-嘉承1:1107-嘉承2:1108-天仁1:1109-天仁2:1110-天永1:1111-天永2:1112-天永3:1113-永久1:1114-永久2:1115-永久3:1116-永久4:1117-永久5:1118-元永1:1119-元永2:1120-保安1:1121-保安2:1122-保安3:1123-保安4:1124-天治1:1125-天治2:1126-大治1:1127-大治2:1128-大治3:1129-大治4:1130-大治5:1131-天承1:1132-長承1:1133-長承2:1134-長承3:1135-保延1:1136-保延2:1137-保延3:1138-保延4:1139-保延5:1140-保延6:1141-永治1:1142-康治1:1143-康治2:1144-天養1:1145-久安1:1146-久安2:1147-久安3:1148-久安4:1149-久安5:1150-久安6:1151-仁平1:1152-仁平2:1153-仁平3:1154-仁平4:1155-久寿2:1156-保元1:1157-保元2:1158-保元3:1159-平治1:1160-永暦1:1161-応保1:1162-応保2:1163-長寛1:1164-長寛2:1165-永万1:1166-仁安1:1167-仁安2:1168-仁安3:1169-嘉応1:1170-嘉応2:1171-承安1:1172-承安2:1173-承安3:1174-承安4:1175-安元1:1176-安元2:1177-治承1:1178-治承2:1179-治承3:1180-治承4:1181-養和1:1182-寿永1:1183-寿永2:1184-元暦1:1185-文治1:1186-文治2:1187-文治3:1188-文治4:1189-文治5:1190-建久1:1191-建久2:1192-建久3:1193-建久4:1194-建久5:1195-建久6:1196-建久7:1197-建久8:1198-建久9:1199-正治1:1200-正治2:1201-建仁1:1202-建仁2:1203-建仁3:1204-元久1:1205-元久2:1206-建永1:1207-建永2:1208-承元2:1209-承元3:1210-承元4:1211-建暦1:1212-建暦2:1213-建暦3:1214-建保2:1215-建保3:1216-建保4:1217-建保5:1218-建保6:1219-承久1:1220-承久2:1221-承久3:1222-貞応1:1223-貞応2:1224-貞応3:1225-嘉禄1:1226-嘉禄2:1227-嘉禄3:1228-安貞2:1229-寛喜1:1230-寛喜2:1231-寛喜3:1232-貞永1:1233-天福1:1234-天福2:1235-嘉禎1:1236-嘉禎2:1237-嘉禎3:1238-嘉禎4:1239-延応1:1240-仁治1:1241-仁治2:1242-仁治3:1243-寛元1:1244-寛元2:1245-寛元3:1246-寛元4:1247-宝治1:1248-宝治2:1249-建長1:1250-建長2:1251-建長3:1252-建長4:1253-建長5:1254-建長6:1255-建長7:1256-康元1:1257-正嘉1:1258-正嘉2:1259-正元1:1260-文応1:1261-弘長1:1262-弘長2:1263-弘長3:1264-文永1:1265-文永2:1266-文永3:1267-文永4:1268-文永5:1269-文永6:1270-文永7:1271-文永8:1272-文永9:1273-文永10:1274-文永11:1275-建治1:1276-建治2:1277-建治3:1278-弘安1:1279-弘安2:1280-弘安3:1281-弘安4:1282-弘安5:1283-弘安6:1284-弘安7:1285-弘安8:1286-弘安9:1287-弘安10:1288-正応1:1289-正応2:1290-正応3:1291-正応4:1292-正応5:1293-永仁1:1294-永仁2:1295-永仁3:1296-永仁4:1297-永仁5:1298-永仁6:1299-正安1:1300-正安2:1301-正安3:1302-正安4:1303-嘉元1:1304-嘉元2:1305-嘉元3:1306-嘉元4:1307-徳治2:1308-延慶1:1309-延慶2:1310-延慶3:1311-応長1:1312-正和1:1313-正和2:1314-正和3:1315-正和4:1316-正和5:1317-文保1:1318-文保2:1319-元応1:1320-元応2:1321-元亨1:1322-元亨2:1323-元亨3:1324-元亨4:1325-正中2:1326-嘉暦1:1327-嘉暦2:1328-嘉暦3:1329-元徳1:1330-元徳2:1331-元弘1:1332-元弘2:1333-元弘3:1334-建武1:1335-建武2:1336-延元1:1337-延元2:1338-延元3:1339-延元4:1340-興国1:1341-興国2:1342-興国3:1343-興国4:1344-興国5:1345-興国6:1346-興国7:1347-正平2:1348-正平3:1349-正平4:1350-正平5:1351-正平6:1352-正平7:1353-正平8:1354-正平9:1355-正平10:1356-正平11:1357-正平12:1358-正平13:1359-正平14:1360-正平15:1361-正平16:1362-正平17:1363-正平18:1364-正平19:1365-正平20:1366-正平21:1367-正平22:1368-正平23:1369-正平24:1370-建徳1:1371-建徳2:1372-文中1:1373-文中2:1374-文中3:1375-天授1:1376-天授2:1377-天授3:1378-天授4:1379-康暦1:1380-康暦2:1381-弘和1:1382-弘和2:1383-弘和3:1384-至徳1:1385-至徳2:1386-至徳3:1387-嘉慶1:1388-嘉慶2:1389-康応1:1390-明徳1:1391-明徳2:1392-明徳3:1393-明徳4:1394-応永1:1395-応永2:1396-応永3:1397-応永4:1398-応永5:1399-応永6:1400-応永7:1401-応永8:1402-応永9:1403-応永10:1404-応永11:1405-応永12:1406-応永13:1407-応永14:1408-応永15:1409-応永16:1410-応永17:1411-応永18:1412-応永19:1413-応永20:1414-応永21:1415-応永22:1416-応永23:1417-応永24:1418-応永25:1419-応永26:1420-応永27:1421-応永28:1422-応永29:1423-応永30:1424-応永31:1425-応永32:1426-応永33:1427-応永34:1428-正長1:1429-永享1:1430-永享2:1431-永享3:1432-永享4:1433-永享5:1434-永享6:1435-永享7:1436-永享8:1437-永享9:1438-永享10:1439-永享11:1440-永享12:1441-嘉吉1:1442-嘉吉2:1443-嘉吉3:1444-文安1:1445-文安2:1446-文安3:1447-文安4:1448-文安5:1449-宝徳1:1450-宝徳2:1451-宝徳3:1452-享徳1:1453-享徳2:1454-享徳3:1455-康正1:1456-康正2:1457-長禄1:1458-長禄2:1459-長禄3:1460-長禄4:1461-寛正2:1462-寛正3:1463-寛正4:1464-寛正5:1465-寛正6:1466-文正1:1467-応仁1:1468-応仁2:1469-文明1:1470-文明2:1471-文明3:1472-文明4:1473-文明5:1474-文明6:1475-文明7:1476-文明8:1477-文明9:1478-文明10:1479-文明11:1480-文明12:1481-文明13:1482-文明14:1483-文明15:1484-文明16:1485-文明17:1486-文明18:1487-長享1:1488-長享2:1489-延徳1:1490-延徳2:1491-延徳3:1492-明応1:1493-明応2:1494-明応3:1495-明応4:1496-明応5:1497-明応6:1498-明応7:1499-明応8:1500-明応9:1501-文亀1:1502-文亀2:1503-文亀3:1504-永正1:1505-永正2:1506-永正3:1507-永正4:1508-永正5:1509-永正6:1510-永正7:1511-永正8:1512-永正9:1513-永正10:1514-永正11:1515-永正12:1516-永正13:1517-永正14:1518-永正15:1519-永正16:1520-永正17:1521-大永1:1522-大永2:1523-大永3:1524-大永4:1525-大永5:1526-大永6:1527-大永7:1528-享禄1:1529-享禄2:1530-享禄3:1531-享禄4:1532-天文1:1533-天文2:1534-天文3:1535-天文4:1536-天文5:1537-天文6:1538-天文7:1539-天文8:1540-天文9:1541-天文10:1542-天文11:1543-天文12:1544-天文13:1545-天文14:1546-天文15:1547-天文16:1548-天文17:1549-天文18:1550-天文19:1551-天文20:1552-天文21:1553-天文22:1554-天文23:1555-天文24:1556-弘治2:1557-弘治3:1558-永禄1:1559-永禄2:1560-永禄3:1561-永禄4:1562-永禄5:1563-永禄6:1564-永禄7:1565-永禄8:1566-永禄9:1567-永禄10:1568-永禄11:1569-永禄12:1570-元亀1:1571-元亀2:1572-元亀3:1573-天正1:1574-天正2:1575-天正3:1576-天正4:1577-天正5:1578-天正6:1579-天正7:1580-天正8:1581-天正9:1582-天正10:1583-天正11:1584-天正12:1585-天正13:1586-天正14:1587-天正15:1588-天正16:1589-天正17:1590-天正18:1591-天正19:1592-天正20:1593-文禄2:1594-文禄3:1595-文禄4:1596-文禄5:1597-慶長2:1598-慶長3:1599-慶長4:1600-慶長5:1601-慶長6:1602-慶長7:1603-慶長8:1604-慶長9:1605-慶長10:1606-慶長11:1607-慶長12:1608-慶長13:1609-慶長14:1610-慶長15:1611-慶長16:1612-慶長17:1613-慶長18:1614-慶長19:1615-元和1:1616-元和2:1617-元和3:1618-元和4:1619-元和5:1620-元和6:1621-元和7:1622-元和8:1623-元和9:1624-寛永1:1625-寛永2:1626-寛永3:1627-寛永4:1628-寛永5:1629-寛永6:1630-寛永7:1631-寛永8:1632-寛永9:1633-寛永10:1634-寛永11:1635-寛永12:1636-寛永13:1637-寛永14:1638-寛永15:1639-寛永16:1640-寛永17:1641-寛永18:1642-寛永19:1643-寛永20:1644-寛永21:1645-正保2:1646-正保3:1647-正保4:1648-慶安1:1649-慶安2:1650-慶安3:1651-慶安4:1652-承応1:1653-承応2:1654-承応3:1655-明暦1:1656-明暦2:1657-明暦3:1658-万治1:1659-万治2:1660-万治3:1661-寛文1:1662-寛文2:1663-寛文3:1664-寛文4:1665-寛文5:1666-寛文6:1667-寛文7:1668-寛文8:1669-寛文9:1670-寛文10:1671-寛文11:1672-寛文12:1673-延宝1:1674-延宝2:1675-延宝3:1676-延宝4:1677-延宝5:1678-延宝6:1679-延宝7:1680-延宝8:1681-天和1:1682-天和2:1683-天和3:1684-貞享1:1685-貞享2:1686-貞享3:1687-貞享4:1688-元禄1:1689-元禄2:1690-元禄3:1691-元禄4:1692-元禄5:1693-元禄6:1694-元禄7:1695-元禄8:1696-元禄9:1697-元禄10:1698-元禄11:1699-元禄12:1700-元禄13:1701-元禄14:1702-元禄15:1703-元禄16:1704-宝永1:1705-宝永2:1706-宝永3:1707-宝永4:1708-宝永5:1709-宝永6:1710-宝永7:1711-正徳1:1712-正徳2:1713-正徳3:1714-正徳4:1715-正徳5:1716-享保1:1717-享保2:1718-享保3:1719-享保4:1720-享保5:1721-享保6:1722-享保7:1723-享保8:1724-享保9:1725-享保10:1726-享保11:1727-享保12:1728-享保13:1729-享保14:1730-享保15:1731-享保16:1732-享保17:1733-享保18:1734-享保19:1735-享保20:1736-元文1:1737-元文2:1738-元文3:1739-元文4:1740-元文5:1741-寛保1:1742-寛保2:1743-寛保3:1744-延享1:1745-延享2:1746-延享3:1747-延享4:1748-寛延1:1749-寛延2:1750-寛延3:1751-寛延4:1752-宝暦2:1753-宝暦3:1754-宝暦4:1755-宝暦5:1756-宝暦6:1757-宝暦7:1758-宝暦8:1759-宝暦9:1760-宝暦10:1761-宝暦11:1762-宝暦12:1763-宝暦13:1764-明和1:1765-明和2:1766-明和3:1767-明和4:1768-明和5:1769-明和6:1770-明和7:1771-明和8:1772-明和9:1773-安永2:1774-安永3:1775-安永4:1776-安永5:1777-安永6:1778-安永7:1779-安永8:1780-安永9:1781-天明1:1782-天明2:1783-天明3:1784-天明4:1785-天明5:1786-天明6:1787-天明7:1788-天明8:1789-寛政1:1790-寛政2:1791-寛政3:1792-寛政4:1793-寛政5:1794-寛政6:1795-寛政7:1796-寛政8:1797-寛政9:1798-寛政10:1799-寛政11:1800-寛政12:1801-享和1:1802-享和2:1803-享和3:1804-文化1:1805-文化2:1806-文化3:1807-文化4:1808-文化5:1809-文化6:1810-文化7:1811-文化8:1812-文化9:1813-文化10:1814-文化11:1815-文化12:1816-文化13:1817-文化14:1818-文政1:1819-文政2:1820-文政3:1821-文政4:1822-文政5:1823-文政6:1824-文政7:1825-文政8:1826-文政9:1827-文政10:1828-文政11:1829-文政12:1830-文政13:1831-天保2:1832-天保3:1833-天保4:1834-天保5:1835-天保6:1836-天保7:1837-天保8:1838-天保9:1839-天保10:1840-天保11:1841-天保12:1842-天保13:1843-天保14:1844-天保15:1845-弘化2:1846-弘化3:1847-弘化4:1848-嘉永1:1849-嘉永2:1850-嘉永3:1851-嘉永4:1852-嘉永5:1853-嘉永6:1854-嘉永7:1855-安政2:1856-安政3:1857-安政4:1858-安政5:1859-安政6:1860-万延1:1861-文久1:1862-文久2:1863-文久3:1864-元治1:1865-慶応1:1866-慶応2:1867-慶応3:1868-明治1:1869-明治2:1870-明治3:1871-明治4:1872-明治5:1873-明治6:1874-明治7:1875-明治8:1876-明治9:1877-明治10:1878-明治11:1879-明治12:1880-明治13:1881-明治14:1882-明治15:1883-明治16:1884-明治17:1885-明治18:1886-明治19:1887-明治20:1888-明治21:1889-明治22:1890-明治23:1891-明治24:1892-明治25:1893-明治26:1894-明治27:1895-明治28:1896-明治29:1897-明治30:1898-明治31:1899-明治32:1900-明治33:1901-明治34:1902-明治35:1903-明治36:1904-明治37:1905-明治38:1906-明治39:1907-明治40:1908-明治41:1909-明治42:1910-明治43:1911-明治44:1912-大正1:1913-大正2:1914-大正3:1915-大正4:1916-大正5:1917-大正6:1918-大正7:1919-大正8:1920-大正9:1921-大正10:1922-大正11:1923-大正12:1924-大正13:1925-大正14:1926-大正15:1927-昭和2:1928-昭和3:1929-昭和4:1930-昭和5:1931-昭和6:1932-昭和7:1933-昭和8:1934-昭和9:1935-昭和10:1936-昭和11:1937-昭和12:1938-昭和13:1939-昭和14:1940-昭和15:1941-昭和16:1942-昭和17:1943-昭和18:1944-昭和19:1945-昭和20:1946-昭和21:1947-昭和22:1948-昭和23:1949-昭和24:1950-昭和25:1951-昭和26:1952-昭和27:1953-昭和28:1954-昭和29:1955-昭和30:1956-昭和31:1957-昭和32:1958-昭和33:1959-昭和34:1960-昭和35:1961-昭和36:1962-昭和37:1963-昭和38:1964-昭和39:1965-昭和40:1966-昭和41:1967-昭和42:1968-昭和43:1969-昭和44:1970-昭和45:1971-昭和46:1972-昭和47:1973-昭和48:1974-昭和49:1975-昭和50:1976-昭和51:1977-昭和52:1978-昭和53:1979-昭和54:1980-昭和55:1981-昭和56:1982-昭和57:1983-昭和58:1984-昭和59:1985-昭和60:1986-昭和61:1987-昭和62:1988-昭和63:1989-平成1:1990-平成2:1991-平成3:1992-平成4:1993-平成5:1994-平成6:1995-平成7:1996-平成8:1997-平成9:1998-平成10:1999-平成11:2000-平成12:2001-平成13:2002-平成14:2003-平成15:2004-平成16:2005-平成17:2006-平成18:2007-平成19:2008-平成20:2009-平成21:2010-平成22:2011-平成23:2012-平成24:2013-平成25:2014-平成26 | ||
+ | </syntaxhighlight2> | ||
+ | |||
+ | タイムゾーン名 | ||
+ | <syntaxhighlight2 lang="text"> | ||
+ | ACT オーストラリア中部標準時 | ||
+ | AET オーストラリア東部標準時 | ||
+ | AGT アルゼンチン標準時 | ||
+ | ART 東ヨーロッパ標準時 | ||
+ | AST アラスカ標準時 | ||
+ | Africa/Abidjan グリニッジ標準時 | ||
+ | Africa/Accra グリニッジ標準時 | ||
+ | Africa/Addis_Ababa 東アフリカ時間 | ||
+ | Africa/Algiers 中央ヨーロッパ標準時 | ||
+ | Africa/Asmara 東アフリカ時間 | ||
+ | Africa/Asmera 東アフリカ時間 | ||
+ | Africa/Bamako グリニッジ標準時 | ||
+ | Africa/Bangui 西アフリカ標準時 | ||
+ | Africa/Banjul グリニッジ標準時 | ||
+ | Africa/Bissau グリニッジ標準時 | ||
+ | Africa/Blantyre 中央アフリカ時間 | ||
+ | Africa/Brazzaville 西アフリカ標準時 | ||
+ | Africa/Bujumbura 中央アフリカ時間 | ||
+ | Africa/Cairo 東ヨーロッパ標準時 | ||
+ | Africa/Casablanca 西ヨーロッパ標準時 | ||
+ | Africa/Ceuta 中央ヨーロッパ標準時 | ||
+ | Africa/Conakry グリニッジ標準時 | ||
+ | Africa/Dakar グリニッジ標準時 | ||
+ | Africa/Dar_es_Salaam 東アフリカ時間 | ||
+ | Africa/Djibouti 東アフリカ時間 | ||
+ | Africa/Douala 西アフリカ標準時 | ||
+ | Africa/El_Aaiun 西ヨーロッパ標準時 | ||
+ | Africa/Freetown グリニッジ標準時 | ||
+ | Africa/Gaborone 中央アフリカ時間 | ||
+ | Africa/Harare 中央アフリカ時間 | ||
+ | Africa/Johannesburg 南アフリカ標準時 | ||
+ | Africa/Juba 東アフリカ時間 | ||
+ | Africa/Kampala 東アフリカ時間 | ||
+ | Africa/Khartoum 東アフリカ時間 | ||
+ | Africa/Kigali 中央アフリカ時間 | ||
+ | Africa/Kinshasa 西アフリカ標準時 | ||
+ | Africa/Lagos 西アフリカ標準時 | ||
+ | Africa/Libreville 西アフリカ標準時 | ||
+ | Africa/Lome グリニッジ標準時 | ||
+ | Africa/Luanda 西アフリカ標準時 | ||
+ | Africa/Lubumbashi 中央アフリカ時間 | ||
+ | Africa/Lusaka 中央アフリカ時間 | ||
+ | Africa/Malabo 西アフリカ標準時 | ||
+ | Africa/Maputo 中央アフリカ時間 | ||
+ | Africa/Maseru 南アフリカ標準時 | ||
+ | Africa/Mbabane 南アフリカ標準時 | ||
+ | Africa/Mogadishu 東アフリカ時間 | ||
+ | Africa/Monrovia グリニッジ標準時 | ||
+ | Africa/Nairobi 東アフリカ時間 | ||
+ | Africa/Ndjamena 西アフリカ標準時 | ||
+ | Africa/Niamey 西アフリカ標準時 | ||
+ | Africa/Nouakchott グリニッジ標準時 | ||
+ | Africa/Ouagadougou グリニッジ標準時 | ||
+ | Africa/Porto-Novo 西アフリカ標準時 | ||
+ | Africa/Sao_Tome グリニッジ標準時 | ||
+ | Africa/Timbuktu グリニッジ標準時 | ||
+ | Africa/Tripoli 東ヨーロッパ標準時 | ||
+ | Africa/Tunis 中央ヨーロッパ標準時 | ||
+ | Africa/Windhoek 西アフリカ標準時 | ||
+ | America/Adak ハワイ・アリューシャン標準時 | ||
+ | America/Anchorage アラスカ標準時 | ||
+ | America/Anguilla 大西洋標準時 | ||
+ | America/Antigua 大西洋標準時 | ||
+ | America/Araguaina ブラジリア標準時 | ||
+ | America/Argentina/Buenos_Aires アルゼンチン標準時 | ||
+ | America/Argentina/Catamarca アルゼンチン標準時 | ||
+ | America/Argentina/ComodRivadavia アルゼンチン標準時 | ||
+ | America/Argentina/Cordoba アルゼンチン標準時 | ||
+ | America/Argentina/Jujuy アルゼンチン標準時 | ||
+ | America/Argentina/La_Rioja アルゼンチン標準時 | ||
+ | America/Argentina/Mendoza アルゼンチン標準時 | ||
+ | America/Argentina/Rio_Gallegos アルゼンチン標準時 | ||
+ | America/Argentina/Salta アルゼンチン標準時 | ||
+ | America/Argentina/San_Juan アルゼンチン標準時 | ||
+ | America/Argentina/San_Luis 西部アルゼンチン標準時 | ||
+ | America/Argentina/Tucuman アルゼンチン標準時 | ||
+ | America/Argentina/Ushuaia アルゼンチン標準時 | ||
+ | America/Aruba 大西洋標準時 | ||
+ | America/Asuncion パラグアイ標準時 | ||
+ | America/Atikokan アメリカ東部標準時 | ||
+ | America/Atka ハワイ・アリューシャン標準時 | ||
+ | America/Bahia ブラジリア標準時 | ||
+ | America/Bahia_Banderas アメリカ中部標準時 | ||
+ | America/Barbados 大西洋標準時 | ||
+ | America/Belem ブラジリア標準時 | ||
+ | America/Belize アメリカ中部標準時 | ||
+ | America/Blanc-Sablon 大西洋標準時 | ||
+ | America/Boa_Vista アマゾン標準時 | ||
+ | America/Bogota コロンビア標準時 | ||
+ | America/Boise アメリカ山地標準時 | ||
+ | America/Buenos_Aires アルゼンチン標準時 | ||
+ | America/Cambridge_Bay アメリカ山地標準時 | ||
+ | America/Campo_Grande アマゾン標準時 | ||
+ | America/Cancun アメリカ中部標準時 | ||
+ | America/Caracas ベネズエラ時間 | ||
+ | America/Catamarca アルゼンチン標準時 | ||
+ | America/Cayenne 仏領ギアナ時間 | ||
+ | America/Cayman アメリカ東部標準時 | ||
+ | America/Chicago アメリカ中部標準時 | ||
+ | America/Chihuahua メキシコ太平洋標準時 | ||
+ | America/Coral_Harbour アメリカ東部標準時 | ||
+ | America/Cordoba アルゼンチン標準時 | ||
+ | America/Costa_Rica アメリカ中部標準時 | ||
+ | America/Creston アメリカ山地標準時 | ||
+ | America/Cuiaba アマゾン標準時 | ||
+ | America/Curacao 大西洋標準時 | ||
+ | America/Danmarkshavn グリニッジ標準時 | ||
+ | America/Dawson アメリカ太平洋標準時 | ||
+ | America/Dawson_Creek アメリカ山地標準時 | ||
+ | America/Denver アメリカ山地標準時 | ||
+ | America/Detroit アメリカ東部標準時 | ||
+ | America/Dominica 大西洋標準時 | ||
+ | America/Edmonton アメリカ山地標準時 | ||
+ | America/Eirunepe アクレ標準時 | ||
+ | America/El_Salvador アメリカ中部標準時 | ||
+ | America/Ensenada アメリカ太平洋標準時 | ||
+ | America/Fort_Wayne アメリカ東部標準時 | ||
+ | America/Fortaleza ブラジリア標準時 | ||
+ | America/Glace_Bay 大西洋標準時 | ||
+ | America/Godthab グリーンランド西部標準時 | ||
+ | America/Goose_Bay 大西洋標準時 | ||
+ | America/Grand_Turk アメリカ東部標準時 | ||
+ | America/Grenada 大西洋標準時 | ||
+ | America/Guadeloupe 大西洋標準時 | ||
+ | America/Guatemala アメリカ中部標準時 | ||
+ | America/Guayaquil エクアドル時間 | ||
+ | America/Guyana ガイアナ時間 | ||
+ | America/Halifax 大西洋標準時 | ||
+ | America/Havana キューバ標準時 | ||
+ | America/Hermosillo メキシコ太平洋標準時 | ||
+ | America/Indiana/Indianapolis アメリカ東部標準時 | ||
+ | America/Indiana/Knox アメリカ中部標準時 | ||
+ | America/Indiana/Marengo アメリカ東部標準時 | ||
+ | America/Indiana/Petersburg アメリカ東部標準時 | ||
+ | America/Indiana/Tell_City アメリカ中部標準時 | ||
+ | America/Indiana/Vevay アメリカ東部標準時 | ||
+ | America/Indiana/Vincennes アメリカ東部標準時 | ||
+ | America/Indiana/Winamac アメリカ東部標準時 | ||
+ | America/Indianapolis アメリカ東部標準時 | ||
+ | America/Inuvik アメリカ山地標準時 | ||
+ | America/Iqaluit アメリカ東部標準時 | ||
+ | America/Jamaica アメリカ東部標準時 | ||
+ | America/Jujuy アルゼンチン標準時 | ||
+ | America/Juneau アラスカ標準時 | ||
+ | America/Kentucky/Louisville アメリカ東部標準時 | ||
+ | America/Kentucky/Monticello アメリカ東部標準時 | ||
+ | America/Knox_IN アメリカ中部標準時 | ||
+ | America/Kralendijk 大西洋標準時 | ||
+ | America/La_Paz ボリビア時間 | ||
+ | America/Lima ペルー標準時 | ||
+ | America/Los_Angeles アメリカ太平洋標準時 | ||
+ | America/Louisville アメリカ東部標準時 | ||
+ | America/Lower_Princes 大西洋標準時 | ||
+ | America/Maceio ブラジリア標準時 | ||
+ | America/Managua アメリカ中部標準時 | ||
+ | America/Manaus アマゾン標準時 | ||
+ | America/Marigot 大西洋標準時 | ||
+ | America/Martinique 大西洋標準時 | ||
+ | America/Matamoros アメリカ中部標準時 | ||
+ | America/Mazatlan メキシコ太平洋標準時 | ||
+ | America/Mendoza アルゼンチン標準時 | ||
+ | America/Menominee アメリカ中部標準時 | ||
+ | America/Merida アメリカ中部標準時 | ||
+ | America/Metlakatla アメリカ太平洋標準時 | ||
+ | America/Mexico_City アメリカ中部標準時 | ||
+ | America/Miquelon サンピエール・ミクロン標準時 | ||
+ | America/Moncton 大西洋標準時 | ||
+ | America/Monterrey アメリカ中部標準時 | ||
+ | America/Montevideo ウルグアイ標準時 | ||
+ | America/Montreal GMT-05:00 | ||
+ | America/Montserrat 大西洋標準時 | ||
+ | America/Nassau アメリカ東部標準時 | ||
+ | America/New_York アメリカ東部標準時 | ||
+ | America/Nipigon アメリカ東部標準時 | ||
+ | America/Nome アラスカ標準時 | ||
+ | America/Noronha フェルナンド・デ・ノローニャ標準時 | ||
+ | America/North_Dakota/Beulah アメリカ中部標準時 | ||
+ | America/North_Dakota/Center アメリカ中部標準時 | ||
+ | America/North_Dakota/New_Salem アメリカ中部標準時 | ||
+ | America/Ojinaga アメリカ山地標準時 | ||
+ | America/Panama アメリカ東部標準時 | ||
+ | America/Pangnirtung アメリカ東部標準時 | ||
+ | America/Paramaribo スリナム時間 | ||
+ | America/Phoenix アメリカ山地標準時 | ||
+ | America/Port-au-Prince アメリカ東部標準時 | ||
+ | America/Port_of_Spain 大西洋標準時 | ||
+ | America/Porto_Acre アクレ標準時 | ||
+ | America/Porto_Velho アマゾン標準時 | ||
+ | America/Puerto_Rico 大西洋標準時 | ||
+ | America/Rainy_River アメリカ中部標準時 | ||
+ | America/Rankin_Inlet アメリカ中部標準時 | ||
+ | America/Recife ブラジリア標準時 | ||
+ | America/Regina アメリカ中部標準時 | ||
+ | America/Resolute アメリカ中部標準時 | ||
+ | America/Rio_Branco アクレ標準時 | ||
+ | America/Rosario アルゼンチン標準時 | ||
+ | America/Santa_Isabel メキシコ北西部標準時 | ||
+ | America/Santarem ブラジリア標準時 | ||
+ | America/Santiago チリ標準時 | ||
+ | America/Santo_Domingo 大西洋標準時 | ||
+ | America/Sao_Paulo ブラジリア標準時 | ||
+ | America/Scoresbysund グリーンランド東部標準時 | ||
+ | America/Shiprock アメリカ山地標準時 | ||
+ | America/Sitka アラスカ標準時 | ||
+ | America/St_Barthelemy 大西洋標準時 | ||
+ | America/St_Johns ニューファンドランド標準時 | ||
+ | America/St_Kitts 大西洋標準時 | ||
+ | America/St_Lucia 大西洋標準時 | ||
+ | America/St_Thomas 大西洋標準時 | ||
+ | America/St_Vincent 大西洋標準時 | ||
+ | America/Swift_Current アメリカ中部標準時 | ||
+ | America/Tegucigalpa アメリカ中部標準時 | ||
+ | America/Thule 大西洋標準時 | ||
+ | America/Thunder_Bay アメリカ東部標準時 | ||
+ | America/Tijuana アメリカ太平洋標準時 | ||
+ | America/Toronto アメリカ東部標準時 | ||
+ | America/Tortola 大西洋標準時 | ||
+ | America/Vancouver アメリカ太平洋標準時 | ||
+ | America/Virgin 大西洋標準時 | ||
+ | America/Whitehorse アメリカ太平洋標準時 | ||
+ | America/Winnipeg アメリカ中部標準時 | ||
+ | America/Yakutat アラスカ標準時 | ||
+ | America/Yellowknife アメリカ山地標準時 | ||
+ | Antarctica/Casey オーストラリア西部標準時 | ||
+ | Antarctica/Davis デービス基地時間 | ||
+ | Antarctica/DumontDUrville デュモン・デュルヴィル基地時間 | ||
+ | Antarctica/Macquarie マッコーリー島時間 | ||
+ | Antarctica/Mawson モーソン基地時間 | ||
+ | Antarctica/McMurdo ニュージーランド標準時 | ||
+ | Antarctica/Palmer チリ標準時 | ||
+ | Antarctica/Rothera ロゼラ基地時間 | ||
+ | Antarctica/South_Pole ニュージーランド標準時 | ||
+ | Antarctica/Syowa 昭和基地時間 | ||
+ | Antarctica/Troll グリニッジ標準時 | ||
+ | Antarctica/Vostok ボストーク基地時間 | ||
+ | Arctic/Longyearbyen 中央ヨーロッパ標準時 | ||
+ | Asia/Aden アラビア標準時 | ||
+ | Asia/Almaty 東カザフスタン時間 | ||
+ | Asia/Amman 東ヨーロッパ標準時 | ||
+ | Asia/Anadyr マガダン標準時 | ||
+ | Asia/Aqtau 西カザフスタン時間 | ||
+ | Asia/Aqtobe 西カザフスタン時間 | ||
+ | Asia/Ashgabat トルクメニスタン標準時 | ||
+ | Asia/Ashkhabad トルクメニスタン標準時 | ||
+ | Asia/Baghdad アラビア標準時 | ||
+ | Asia/Bahrain アラビア標準時 | ||
+ | Asia/Baku アゼルバイジャン標準時 | ||
+ | Asia/Bangkok インドシナ時間 | ||
+ | Asia/Beirut 東ヨーロッパ標準時 | ||
+ | Asia/Bishkek キルギスタン時間 | ||
+ | Asia/Brunei ブルネイ・ダルサラーム時間 | ||
+ | Asia/Calcutta インド標準時 | ||
+ | Asia/Chita ヤクーツク標準時 | ||
+ | Asia/Choibalsan チョイバルサン標準時 | ||
+ | Asia/Chongqing 中国標準時 | ||
+ | Asia/Chungking 中国標準時 | ||
+ | Asia/Colombo インド標準時 | ||
+ | Asia/Dacca バングラデシュ標準時 | ||
+ | Asia/Damascus 東ヨーロッパ標準時 | ||
+ | Asia/Dhaka バングラデシュ標準時 | ||
+ | Asia/Dili 東ティモール時間 | ||
+ | Asia/Dubai 湾岸標準時 | ||
+ | Asia/Dushanbe タジキスタン時間 | ||
+ | Asia/Gaza 東ヨーロッパ標準時 | ||
+ | Asia/Harbin 中国標準時 | ||
+ | Asia/Hebron 東ヨーロッパ標準時 | ||
+ | Asia/Ho_Chi_Minh インドシナ時間 | ||
+ | Asia/Hong_Kong 香港標準時 | ||
+ | Asia/Hovd ホブド標準時 | ||
+ | Asia/Irkutsk イルクーツク標準時 | ||
+ | Asia/Istanbul 東ヨーロッパ標準時 | ||
+ | Asia/Jakarta インドネシア西部時間 | ||
+ | Asia/Jayapura インドネシア東部時間 | ||
+ | Asia/Jerusalem イスラエル標準時 | ||
+ | Asia/Kabul アフガニスタン時間 | ||
+ | Asia/Kamchatka マガダン標準時 | ||
+ | Asia/Karachi パキスタン標準時 | ||
+ | Asia/Kashgar GMT+06:00 | ||
+ | Asia/Kathmandu ネパール時間 | ||
+ | Asia/Katmandu ネパール時間 | ||
+ | Asia/Khandyga ヤクーツク標準時 | ||
+ | Asia/Kolkata インド標準時 | ||
+ | Asia/Krasnoyarsk クラスノヤルスク標準時 | ||
+ | Asia/Kuala_Lumpur マレーシア時間 | ||
+ | Asia/Kuching マレーシア時間 | ||
+ | Asia/Kuwait アラビア標準時 | ||
+ | Asia/Macao 中国標準時 | ||
+ | Asia/Macau 中国標準時 | ||
+ | Asia/Magadan マガダン標準時 | ||
+ | Asia/Makassar インドネシア中部時間 | ||
+ | Asia/Manila フィリピン標準時 | ||
+ | Asia/Muscat 湾岸標準時 | ||
+ | Asia/Nicosia 東ヨーロッパ標準時 | ||
+ | Asia/Novokuznetsk ノヴォシビルスク標準時 | ||
+ | Asia/Novosibirsk ノヴォシビルスク標準時 | ||
+ | Asia/Omsk オムスク標準時 | ||
+ | Asia/Oral 西カザフスタン時間 | ||
+ | Asia/Phnom_Penh インドシナ時間 | ||
+ | Asia/Pontianak インドネシア西部時間 | ||
+ | Asia/Pyongyang 韓国標準時 | ||
+ | Asia/Qatar アラビア標準時 | ||
+ | Asia/Qyzylorda 東カザフスタン時間 | ||
+ | Asia/Rangoon ミャンマー時間 | ||
+ | Asia/Riyadh アラビア標準時 | ||
+ | Asia/Saigon インドシナ時間 | ||
+ | Asia/Sakhalin サハリン標準時 | ||
+ | Asia/Samarkand ウズベキスタン標準時 | ||
+ | Asia/Seoul 韓国標準時 | ||
+ | Asia/Shanghai 中国標準時 | ||
+ | Asia/Singapore シンガポール標準時 | ||
+ | Asia/Srednekolymsk マガダン標準時 | ||
+ | Asia/Taipei 台北標準時 | ||
+ | Asia/Tashkent ウズベキスタン標準時 | ||
+ | Asia/Tbilisi グルジア標準時 | ||
+ | Asia/Tehran イラン標準時 | ||
+ | Asia/Tel_Aviv イスラエル標準時 | ||
+ | Asia/Thimbu ブータン時間 | ||
+ | Asia/Thimphu ブータン時間 | ||
+ | Asia/Tokyo 日本標準時 | ||
+ | Asia/Ujung_Pandang インドネシア中部時間 | ||
+ | Asia/Ulaanbaatar ウランバートル標準時 | ||
+ | Asia/Ulan_Bator ウランバートル標準時 | ||
+ | Asia/Urumqi GMT+06:00 | ||
+ | Asia/Ust-Nera ウラジオストク標準時 | ||
+ | Asia/Vientiane インドシナ時間 | ||
+ | Asia/Vladivostok ウラジオストク標準時 | ||
+ | Asia/Yakutsk ヤクーツク標準時 | ||
+ | Asia/Yekaterinburg エカテリンブルグ標準時 | ||
+ | Asia/Yerevan アルメニア標準時 | ||
+ | Atlantic/Azores アゾレス標準時 | ||
+ | Atlantic/Bermuda 大西洋標準時 | ||
+ | Atlantic/Canary 西ヨーロッパ標準時 | ||
+ | Atlantic/Cape_Verde カーボベルデ標準時 | ||
+ | Atlantic/Faeroe 西ヨーロッパ標準時 | ||
+ | Atlantic/Faroe 西ヨーロッパ標準時 | ||
+ | Atlantic/Jan_Mayen 中央ヨーロッパ標準時 | ||
+ | Atlantic/Madeira 西ヨーロッパ標準時 | ||
+ | Atlantic/Reykjavik グリニッジ標準時 | ||
+ | Atlantic/South_Georgia サウスジョージア時間 | ||
+ | Atlantic/St_Helena グリニッジ標準時 | ||
+ | Atlantic/Stanley フォークランド諸島標準時 | ||
+ | Australia/ACT オーストラリア東部標準時 | ||
+ | Australia/Adelaide オーストラリア中部標準時 | ||
+ | Australia/Brisbane オーストラリア東部標準時 | ||
+ | Australia/Broken_Hill オーストラリア中部標準時 | ||
+ | Australia/Canberra オーストラリア東部標準時 | ||
+ | Australia/Currie オーストラリア東部標準時 | ||
+ | Australia/Darwin オーストラリア中部標準時 | ||
+ | Australia/Eucla オーストラリア中西部標準時 | ||
+ | Australia/Hobart オーストラリア東部標準時 | ||
+ | Australia/LHI ロードハウ標準時 | ||
+ | Australia/Lindeman オーストラリア東部標準時 | ||
+ | Australia/Lord_Howe ロードハウ標準時 | ||
+ | Australia/Melbourne オーストラリア東部標準時 | ||
+ | Australia/NSW オーストラリア東部標準時 | ||
+ | Australia/North オーストラリア中部標準時 | ||
+ | Australia/Perth オーストラリア西部標準時 | ||
+ | Australia/Queensland オーストラリア東部標準時 | ||
+ | Australia/South オーストラリア中部標準時 | ||
+ | Australia/Sydney オーストラリア東部標準時 | ||
+ | Australia/Tasmania オーストラリア東部標準時 | ||
+ | Australia/Victoria オーストラリア東部標準時 | ||
+ | Australia/West オーストラリア西部標準時 | ||
+ | Australia/Yancowinna オーストラリア中部標準時 | ||
+ | BET ブラジリア標準時 | ||
+ | BST バングラデシュ標準時 | ||
+ | Brazil/Acre アクレ標準時 | ||
+ | Brazil/DeNoronha フェルナンド・デ・ノローニャ標準時 | ||
+ | Brazil/East ブラジリア標準時 | ||
+ | Brazil/West アマゾン標準時 | ||
+ | CAT 中央アフリカ時間 | ||
+ | CET GMT+01:00 | ||
+ | CNT ニューファンドランド標準時 | ||
+ | CST アメリカ中部標準時 | ||
+ | CST6CDT アメリカ中部標準時 | ||
+ | CTT 中国標準時 | ||
+ | Canada/Atlantic 大西洋標準時 | ||
+ | Canada/Central アメリカ中部標準時 | ||
+ | Canada/East-Saskatchewan アメリカ中部標準時 | ||
+ | Canada/Eastern アメリカ東部標準時 | ||
+ | Canada/Mountain アメリカ山地標準時 | ||
+ | Canada/Newfoundland ニューファンドランド標準時 | ||
+ | Canada/Pacific アメリカ太平洋標準時 | ||
+ | Canada/Saskatchewan アメリカ中部標準時 | ||
+ | Canada/Yukon アメリカ太平洋標準時 | ||
+ | Chile/Continental チリ標準時 | ||
+ | Chile/EasterIsland イースター島標準時 | ||
+ | Cuba キューバ標準時 | ||
+ | EAT 東アフリカ時間 | ||
+ | ECT 中央ヨーロッパ標準時 | ||
+ | EET GMT+02:00 | ||
+ | EST GMT-05:00 | ||
+ | EST5EDT アメリカ東部標準時 | ||
+ | Egypt 東ヨーロッパ標準時 | ||
+ | Eire グリニッジ標準時 | ||
+ | Etc/GMT GMT | ||
+ | Etc/GMT+0 GMT | ||
+ | Etc/GMT+1 GMT-01:00 | ||
+ | Etc/GMT+10 GMT-10:00 | ||
+ | Etc/GMT+11 GMT-11:00 | ||
+ | Etc/GMT+12 GMT-12:00 | ||
+ | Etc/GMT+2 GMT-02:00 | ||
+ | Etc/GMT+3 GMT-03:00 | ||
+ | Etc/GMT+4 GMT-04:00 | ||
+ | Etc/GMT+5 GMT-05:00 | ||
+ | Etc/GMT+6 GMT-06:00 | ||
+ | Etc/GMT+7 GMT-07:00 | ||
+ | Etc/GMT+8 GMT-08:00 | ||
+ | Etc/GMT+9 GMT-09:00 | ||
+ | Etc/GMT-0 GMT | ||
+ | Etc/GMT-1 GMT+01:00 | ||
+ | Etc/GMT-10 GMT+10:00 | ||
+ | Etc/GMT-11 GMT+11:00 | ||
+ | Etc/GMT-12 GMT+12:00 | ||
+ | Etc/GMT-13 GMT+13:00 | ||
+ | Etc/GMT-14 GMT+14:00 | ||
+ | Etc/GMT-2 GMT+02:00 | ||
+ | Etc/GMT-3 GMT+03:00 | ||
+ | Etc/GMT-4 GMT+04:00 | ||
+ | Etc/GMT-5 GMT+05:00 | ||
+ | Etc/GMT-6 GMT+06:00 | ||
+ | Etc/GMT-7 GMT+07:00 | ||
+ | Etc/GMT-8 GMT+08:00 | ||
+ | Etc/GMT-9 GMT+09:00 | ||
+ | Etc/GMT0 GMT | ||
+ | Etc/Greenwich GMT | ||
+ | Etc/UCT GMT | ||
+ | Etc/UTC GMT | ||
+ | Etc/Universal GMT | ||
+ | Etc/Zulu GMT | ||
+ | Europe/Amsterdam 中央ヨーロッパ標準時 | ||
+ | Europe/Andorra 中央ヨーロッパ標準時 | ||
+ | Europe/Athens 東ヨーロッパ標準時 | ||
+ | Europe/Belfast グリニッジ標準時 | ||
+ | Europe/Belgrade 中央ヨーロッパ標準時 | ||
+ | Europe/Berlin 中央ヨーロッパ標準時 | ||
+ | Europe/Bratislava 中央ヨーロッパ標準時 | ||
+ | Europe/Brussels 中央ヨーロッパ標準時 | ||
+ | Europe/Bucharest 東ヨーロッパ標準時 | ||
+ | Europe/Budapest 中央ヨーロッパ標準時 | ||
+ | Europe/Busingen 中央ヨーロッパ標準時 | ||
+ | Europe/Chisinau 東ヨーロッパ標準時 | ||
+ | Europe/Copenhagen 中央ヨーロッパ標準時 | ||
+ | Europe/Dublin グリニッジ標準時 | ||
+ | Europe/Gibraltar 中央ヨーロッパ標準時 | ||
+ | Europe/Guernsey グリニッジ標準時 | ||
+ | Europe/Helsinki 東ヨーロッパ標準時 | ||
+ | Europe/Isle_of_Man グリニッジ標準時 | ||
+ | Europe/Istanbul 東ヨーロッパ標準時 | ||
+ | Europe/Jersey グリニッジ標準時 | ||
+ | Europe/Kaliningrad 極東ヨーロッパ時間 | ||
+ | Europe/Kiev 東ヨーロッパ標準時 | ||
+ | Europe/Lisbon 西ヨーロッパ標準時 | ||
+ | Europe/Ljubljana 中央ヨーロッパ標準時 | ||
+ | Europe/London グリニッジ標準時 | ||
+ | Europe/Luxembourg 中央ヨーロッパ標準時 | ||
+ | Europe/Madrid 中央ヨーロッパ標準時 | ||
+ | Europe/Malta 中央ヨーロッパ標準時 | ||
+ | Europe/Mariehamn 東ヨーロッパ標準時 | ||
+ | Europe/Minsk 極東ヨーロッパ時間 | ||
+ | Europe/Monaco 中央ヨーロッパ標準時 | ||
+ | Europe/Moscow モスクワ標準時 | ||
+ | Europe/Nicosia 東ヨーロッパ標準時 | ||
+ | Europe/Oslo 中央ヨーロッパ標準時 | ||
+ | Europe/Paris 中央ヨーロッパ標準時 | ||
+ | Europe/Podgorica 中央ヨーロッパ標準時 | ||
+ | Europe/Prague 中央ヨーロッパ標準時 | ||
+ | Europe/Riga 東ヨーロッパ標準時 | ||
+ | Europe/Rome 中央ヨーロッパ標準時 | ||
+ | Europe/Samara モスクワ標準時 | ||
+ | Europe/San_Marino 中央ヨーロッパ標準時 | ||
+ | Europe/Sarajevo 中央ヨーロッパ標準時 | ||
+ | Europe/Simferopol モスクワ標準時 | ||
+ | Europe/Skopje 中央ヨーロッパ標準時 | ||
+ | Europe/Sofia 東ヨーロッパ標準時 | ||
+ | Europe/Stockholm 中央ヨーロッパ標準時 | ||
+ | Europe/Tallinn 東ヨーロッパ標準時 | ||
+ | Europe/Tirane 中央ヨーロッパ標準時 | ||
+ | Europe/Tiraspol 東ヨーロッパ標準時 | ||
+ | Europe/Uzhgorod 東ヨーロッパ標準時 | ||
+ | Europe/Vaduz 中央ヨーロッパ標準時 | ||
+ | Europe/Vatican 中央ヨーロッパ標準時 | ||
+ | Europe/Vienna 中央ヨーロッパ標準時 | ||
+ | Europe/Vilnius 東ヨーロッパ標準時 | ||
+ | Europe/Volgograd モスクワ標準時 | ||
+ | Europe/Warsaw 中央ヨーロッパ標準時 | ||
+ | Europe/Zagreb 中央ヨーロッパ標準時 | ||
+ | Europe/Zaporozhye 東ヨーロッパ標準時 | ||
+ | Europe/Zurich 中央ヨーロッパ標準時 | ||
+ | Factory GMT | ||
+ | GB グリニッジ標準時 | ||
+ | GB-Eire グリニッジ標準時 | ||
+ | GMT GMT | ||
+ | GMT+0 GMT | ||
+ | GMT-0 GMT | ||
+ | GMT0 GMT | ||
+ | Greenwich GMT | ||
+ | HST GMT-10:00 | ||
+ | Hongkong 香港標準時 | ||
+ | IET アメリカ東部標準時 | ||
+ | IST インド標準時 | ||
+ | Iceland グリニッジ標準時 | ||
+ | Indian/Antananarivo 東アフリカ時間 | ||
+ | Indian/Chagos インド洋時間 | ||
+ | Indian/Christmas クリスマス島時間 | ||
+ | Indian/Cocos ココス諸島時間 | ||
+ | Indian/Comoro 東アフリカ時間 | ||
+ | Indian/Kerguelen 仏領南方南極時間 | ||
+ | Indian/Mahe セーシェル時間 | ||
+ | Indian/Maldives モルディブ時間 | ||
+ | Indian/Mauritius モーリシャス標準時 | ||
+ | Indian/Mayotte 東アフリカ時間 | ||
+ | Indian/Reunion レユニオン時間 | ||
+ | Iran イラン標準時 | ||
+ | Israel イスラエル標準時 | ||
+ | JST 日本標準時 | ||
+ | Jamaica アメリカ東部標準時 | ||
+ | Japan 日本標準時 | ||
+ | Kwajalein マーシャル諸島時間 | ||
+ | Libya 東ヨーロッパ標準時 | ||
+ | MET GMT+01:00 | ||
+ | MIT アピーア標準時 | ||
+ | MST GMT-07:00 | ||
+ | MST7MDT アメリカ山地標準時 | ||
+ | Mexico/BajaNorte アメリカ太平洋標準時 | ||
+ | Mexico/BajaSur メキシコ太平洋標準時 | ||
+ | Mexico/General アメリカ中部標準時 | ||
+ | NET アルメニア標準時 | ||
+ | NST ニュージーランド標準時 | ||
+ | NZ ニュージーランド標準時 | ||
+ | NZ-CHAT チャタム標準時 | ||
+ | Navajo アメリカ山地標準時 | ||
+ | PLT パキスタン標準時 | ||
+ | PNT アメリカ山地標準時 | ||
+ | PRC 中国標準時 | ||
+ | PRT 大西洋標準時 | ||
+ | PST アメリカ太平洋標準時 | ||
+ | PST8PDT アメリカ太平洋標準時 | ||
+ | Pacific/Apia アピーア標準時 | ||
+ | Pacific/Auckland ニュージーランド標準時 | ||
+ | Pacific/Chatham チャタム標準時 | ||
+ | Pacific/Chuuk チューク時間 | ||
+ | Pacific/Easter イースター島標準時 | ||
+ | Pacific/Efate バヌアツ標準時 | ||
+ | Pacific/Enderbury フェニックス諸島時間 | ||
+ | Pacific/Fakaofo トケラウ時間 | ||
+ | Pacific/Fiji フィジー標準時 | ||
+ | Pacific/Funafuti ツバル時間 | ||
+ | Pacific/Galapagos ガラパゴス時間 | ||
+ | Pacific/Gambier ガンビエ諸島時間 | ||
+ | Pacific/Guadalcanal ソロモン諸島時間 | ||
+ | Pacific/Guam チャモロ時間 | ||
+ | Pacific/Honolulu ハワイ・アリューシャン標準時 | ||
+ | Pacific/Johnston ハワイ・アリューシャン標準時 | ||
+ | Pacific/Kiritimati ライン諸島時間 | ||
+ | Pacific/Kosrae コスラエ時間 | ||
+ | Pacific/Kwajalein マーシャル諸島時間 | ||
+ | Pacific/Majuro マーシャル諸島時間 | ||
+ | Pacific/Marquesas マルキーズ時間 | ||
+ | Pacific/Midway サモア標準時 | ||
+ | Pacific/Nauru ナウル時間 | ||
+ | Pacific/Niue ニウエ時間 | ||
+ | Pacific/Norfolk ノーフォーク島時間 | ||
+ | Pacific/Noumea ニューカレドニア標準時 | ||
+ | Pacific/Pago_Pago サモア標準時 | ||
+ | Pacific/Palau パラオ時間 | ||
+ | Pacific/Pitcairn ピトケアン時間 | ||
+ | Pacific/Pohnpei ポナペ時間 | ||
+ | Pacific/Ponape ポナペ時間 | ||
+ | Pacific/Port_Moresby パプアニューギニア時間 | ||
+ | Pacific/Rarotonga クック諸島標準時 | ||
+ | Pacific/Saipan チャモロ時間 | ||
+ | Pacific/Samoa サモア標準時 | ||
+ | Pacific/Tahiti タヒチ時間 | ||
+ | Pacific/Tarawa ギルバート諸島時間 | ||
+ | Pacific/Tongatapu トンガ標準時 | ||
+ | Pacific/Truk チューク時間 | ||
+ | Pacific/Wake ウェーク島時間 | ||
+ | Pacific/Wallis ウォリス・フツナ時間 | ||
+ | Pacific/Yap チューク時間 | ||
+ | Poland 中央ヨーロッパ標準時 | ||
+ | Portugal 西ヨーロッパ標準時 | ||
+ | ROC 台北標準時 | ||
+ | ROK 韓国標準時 | ||
+ | SST ソロモン諸島時間 | ||
+ | Singapore シンガポール標準時 | ||
+ | SystemV/AST4 GMT-04:00 | ||
+ | SystemV/AST4ADT GMT-04:00 | ||
+ | SystemV/CST6 GMT-06:00 | ||
+ | SystemV/CST6CDT GMT-06:00 | ||
+ | SystemV/EST5 GMT-05:00 | ||
+ | SystemV/EST5EDT GMT-05:00 | ||
+ | SystemV/HST10 GMT-10:00 | ||
+ | SystemV/MST7 GMT-07:00 | ||
+ | SystemV/MST7MDT GMT-07:00 | ||
+ | SystemV/PST8 GMT-08:00 | ||
+ | SystemV/PST8PDT GMT-08:00 | ||
+ | SystemV/YST9 GMT-09:00 | ||
+ | SystemV/YST9YDT GMT-09:00 | ||
+ | Turkey 東ヨーロッパ標準時 | ||
+ | UCT GMT | ||
+ | US/Alaska アラスカ標準時 | ||
+ | US/Aleutian ハワイ・アリューシャン標準時 | ||
+ | US/Arizona アメリカ山地標準時 | ||
+ | US/Central アメリカ中部標準時 | ||
+ | US/East-Indiana アメリカ東部標準時 | ||
+ | US/Eastern アメリカ東部標準時 | ||
+ | US/Hawaii ハワイ・アリューシャン標準時 | ||
+ | US/Indiana-Starke アメリカ中部標準時 | ||
+ | US/Michigan アメリカ東部標準時 | ||
+ | US/Mountain アメリカ山地標準時 | ||
+ | US/Pacific アメリカ太平洋標準時 | ||
+ | US/Pacific-New アメリカ太平洋標準時 | ||
+ | US/Samoa サモア標準時 | ||
+ | UTC GMT | ||
+ | Universal GMT | ||
+ | VST インドシナ時間 | ||
+ | W-SU モスクワ標準時 | ||
+ | WET GMT | ||
+ | Zulu GMT | ||
+ | |||
+ | </syntaxhighlight2> | ||
+ | |||
+ | 各言語での日本時間の表記 | ||
+ | <syntaxhighlight2 lang="text"> | ||
+ | Asia/Tokyo af Japan-standaardtyd | ||
+ | Asia/Tokyo af_NA Japan-standaardtyd | ||
+ | Asia/Tokyo af_ZA Japan-standaardtyd | ||
+ | Asia/Tokyo agq GMT+09:00 | ||
+ | Asia/Tokyo agq_CM GMT+09:00 | ||
+ | Asia/Tokyo ak GMT+09:00 | ||
+ | Asia/Tokyo ak_GH GMT+09:00 | ||
+ | Asia/Tokyo am የጃፓን መደበኛ ሰዓት | ||
+ | Asia/Tokyo am_ET የጃፓን መደበኛ ሰዓት | ||
+ | Asia/Tokyo ar توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_001 توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_AE توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_BH توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_DJ توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_DZ توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_EG توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_EH توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_ER توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_IL توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_IQ توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_JO توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_KM توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_KW توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_LB توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_LY توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_MA توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_MR توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_OM توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_PS توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_QA توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_SA توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_SD توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_SO توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_SS توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_SY توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_TD توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_TN توقيت اليابان الرسمي | ||
+ | Asia/Tokyo ar_YE توقيت اليابان الرسمي | ||
+ | Asia/Tokyo as GMT+০৯:০০ | ||
+ | Asia/Tokyo as_IN GMT+০৯:০০ | ||
+ | Asia/Tokyo asa GMT+09:00 | ||
+ | Asia/Tokyo asa_TZ GMT+09:00 | ||
+ | Asia/Tokyo az Yaponiya Standart Vaxtı | ||
+ | Asia/Tokyo az_Cyrl GMT+09:00 | ||
+ | Asia/Tokyo az_Cyrl_AZ GMT+09:00 | ||
+ | Asia/Tokyo az_Latn Yaponiya Standart Vaxtı | ||
+ | Asia/Tokyo az_Latn_AZ Yaponiya Standart Vaxtı | ||
+ | Asia/Tokyo bas GMT+09:00 | ||
+ | Asia/Tokyo bas_CM GMT+09:00 | ||
+ | Asia/Tokyo be GMT+09:00 | ||
+ | Asia/Tokyo be_BY GMT+09:00 | ||
+ | Asia/Tokyo bem GMT+09:00 | ||
+ | Asia/Tokyo bem_ZM GMT+09:00 | ||
+ | Asia/Tokyo bez GMT+09:00 | ||
+ | Asia/Tokyo bez_TZ GMT+09:00 | ||
+ | Asia/Tokyo bg Японско стандартно време | ||
+ | Asia/Tokyo bg_BG Японско стандартно време | ||
+ | Asia/Tokyo bm GMT+09:00 | ||
+ | Asia/Tokyo bm_Latn GMT+09:00 | ||
+ | Asia/Tokyo bm_Latn_ML GMT+09:00 | ||
+ | Asia/Tokyo bn জাপান মানক সময় | ||
+ | Asia/Tokyo bn_BD জাপান মানক সময় | ||
+ | Asia/Tokyo bn_IN জাপান মানক সময় | ||
+ | Asia/Tokyo bo GMT+09:00 | ||
+ | Asia/Tokyo bo_CN GMT+09:00 | ||
+ | Asia/Tokyo bo_IN GMT+09:00 | ||
+ | Asia/Tokyo br GMT+09:00 | ||
+ | Asia/Tokyo br_FR GMT+09:00 | ||
+ | Asia/Tokyo brx जपान स्टैंडर्ड टाईम | ||
+ | Asia/Tokyo brx_IN जपान स्टैंडर्ड टाईम | ||
+ | Asia/Tokyo bs Standardno japansko vrijeme | ||
+ | Asia/Tokyo bs_Cyrl Јапанско стандардно време | ||
+ | Asia/Tokyo bs_Cyrl_BA Јапанско стандардно време | ||
+ | Asia/Tokyo bs_Latn Standardno japansko vrijeme | ||
+ | Asia/Tokyo bs_Latn_BA Standardno japansko vrijeme | ||
+ | Asia/Tokyo ca Hora estàndard del Japó | ||
+ | Asia/Tokyo ca_AD Hora estàndard del Japó | ||
+ | Asia/Tokyo ca_ES Hora estàndard del Japó | ||
+ | Asia/Tokyo ca_FR Hora estàndard del Japó | ||
+ | Asia/Tokyo ca_IT Hora estàndard del Japó | ||
+ | Asia/Tokyo cgg GMT+09:00 | ||
+ | Asia/Tokyo cgg_UG GMT+09:00 | ||
+ | Asia/Tokyo chr GMT+09:00 | ||
+ | Asia/Tokyo chr_US GMT+09:00 | ||
+ | Asia/Tokyo cs Japonský standardní čas | ||
+ | Asia/Tokyo cs_CZ Japonský standardní čas | ||
+ | Asia/Tokyo cy Amser Safonol Japan | ||
+ | Asia/Tokyo cy_GB Amser Safonol Japan | ||
+ | Asia/Tokyo da Japansk normaltid | ||
+ | Asia/Tokyo da_DK Japansk normaltid | ||
+ | Asia/Tokyo da_GL Japansk normaltid | ||
+ | Asia/Tokyo dav GMT+09:00 | ||
+ | Asia/Tokyo dav_KE GMT+09:00 | ||
+ | Asia/Tokyo de Japanische Normalzeit | ||
+ | Asia/Tokyo de_AT Japanische Normalzeit | ||
+ | Asia/Tokyo de_BE Japanische Normalzeit | ||
+ | Asia/Tokyo de_CH Japanische Normalzeit | ||
+ | Asia/Tokyo de_DE Japanische Normalzeit | ||
+ | Asia/Tokyo de_LI Japanische Normalzeit | ||
+ | Asia/Tokyo de_LU Japanische Normalzeit | ||
+ | Asia/Tokyo dje GMT+09:00 | ||
+ | Asia/Tokyo dje_NE GMT+09:00 | ||
+ | Asia/Tokyo dsb Japański standardny cas | ||
+ | Asia/Tokyo dsb_DE Japański standardny cas | ||
+ | Asia/Tokyo dua GMT+09:00 | ||
+ | Asia/Tokyo dua_CM GMT+09:00 | ||
+ | Asia/Tokyo dyo GMT+09:00 | ||
+ | Asia/Tokyo dyo_SN GMT+09:00 | ||
+ | Asia/Tokyo dz ཇ་པཱན་ཚད་ལྡན་ཆུ་ཚོད | ||
+ | Asia/Tokyo dz_BT ཇ་པཱན་ཚད་ལྡན་ཆུ་ཚོད | ||
+ | Asia/Tokyo ebu GMT+09:00 | ||
+ | Asia/Tokyo ebu_KE GMT+09:00 | ||
+ | Asia/Tokyo ee GMT+09:00 | ||
+ | Asia/Tokyo ee_GH GMT+09:00 | ||
+ | Asia/Tokyo ee_TG GMT+09:00 | ||
+ | Asia/Tokyo el Χειμερινή ώρα Ιαπωνίας | ||
+ | Asia/Tokyo el_CY Χειμερινή ώρα Ιαπωνίας | ||
+ | Asia/Tokyo el_GR Χειμερινή ώρα Ιαπωνίας | ||
+ | Asia/Tokyo en Japan Standard Time | ||
+ | Asia/Tokyo en_001 Japan Standard Time | ||
+ | Asia/Tokyo en_150 Japan Standard Time | ||
+ | Asia/Tokyo en_AG Japan Standard Time | ||
+ | Asia/Tokyo en_AI Japan Standard Time | ||
+ | Asia/Tokyo en_AS Japan Standard Time | ||
+ | Asia/Tokyo en_AU Japan Standard Time | ||
+ | Asia/Tokyo en_BB Japan Standard Time | ||
+ | Asia/Tokyo en_BE Japan Standard Time | ||
+ | Asia/Tokyo en_BM Japan Standard Time | ||
+ | Asia/Tokyo en_BS Japan Standard Time | ||
+ | Asia/Tokyo en_BW Japan Standard Time | ||
+ | Asia/Tokyo en_BZ Japan Standard Time | ||
+ | Asia/Tokyo en_CA Japan Standard Time | ||
+ | Asia/Tokyo en_CC Japan Standard Time | ||
+ | Asia/Tokyo en_CK Japan Standard Time | ||
+ | Asia/Tokyo en_CM Japan Standard Time | ||
+ | Asia/Tokyo en_CX Japan Standard Time | ||
+ | Asia/Tokyo en_DG Japan Standard Time | ||
+ | Asia/Tokyo en_DM Japan Standard Time | ||
+ | Asia/Tokyo en_ER Japan Standard Time | ||
+ | Asia/Tokyo en_FJ Japan Standard Time | ||
+ | Asia/Tokyo en_FK Japan Standard Time | ||
+ | Asia/Tokyo en_FM Japan Standard Time | ||
+ | Asia/Tokyo en_GB Japan Standard Time | ||
+ | Asia/Tokyo en_GD Japan Standard Time | ||
+ | Asia/Tokyo en_GG Japan Standard Time | ||
+ | Asia/Tokyo en_GH Japan Standard Time | ||
+ | Asia/Tokyo en_GI Japan Standard Time | ||
+ | Asia/Tokyo en_GM Japan Standard Time | ||
+ | Asia/Tokyo en_GU Japan Standard Time | ||
+ | Asia/Tokyo en_GY Japan Standard Time | ||
+ | Asia/Tokyo en_HK Japan Standard Time | ||
+ | Asia/Tokyo en_IE Japan Standard Time | ||
+ | Asia/Tokyo en_IM Japan Standard Time | ||
+ | Asia/Tokyo en_IN Japan Standard Time | ||
+ | Asia/Tokyo en_IO Japan Standard Time | ||
+ | Asia/Tokyo en_JE Japan Standard Time | ||
+ | Asia/Tokyo en_JM Japan Standard Time | ||
+ | Asia/Tokyo en_KE Japan Standard Time | ||
+ | Asia/Tokyo en_KI Japan Standard Time | ||
+ | Asia/Tokyo en_KN Japan Standard Time | ||
+ | Asia/Tokyo en_KY Japan Standard Time | ||
+ | Asia/Tokyo en_LC Japan Standard Time | ||
+ | Asia/Tokyo en_LR Japan Standard Time | ||
+ | Asia/Tokyo en_LS Japan Standard Time | ||
+ | Asia/Tokyo en_MG Japan Standard Time | ||
+ | Asia/Tokyo en_MH Japan Standard Time | ||
+ | Asia/Tokyo en_MO Japan Standard Time | ||
+ | Asia/Tokyo en_MP Japan Standard Time | ||
+ | Asia/Tokyo en_MS Japan Standard Time | ||
+ | Asia/Tokyo en_MT Japan Standard Time | ||
+ | Asia/Tokyo en_MU Japan Standard Time | ||
+ | Asia/Tokyo en_MW Japan Standard Time | ||
+ | Asia/Tokyo en_MY Japan Standard Time | ||
+ | Asia/Tokyo en_NA Japan Standard Time | ||
+ | Asia/Tokyo en_NF Japan Standard Time | ||
+ | Asia/Tokyo en_NG Japan Standard Time | ||
+ | Asia/Tokyo en_NR Japan Standard Time | ||
+ | Asia/Tokyo en_NU Japan Standard Time | ||
+ | Asia/Tokyo en_NZ Japan Standard Time | ||
+ | Asia/Tokyo en_PG Japan Standard Time | ||
+ | Asia/Tokyo en_PH Japan Standard Time | ||
+ | Asia/Tokyo en_PK Japan Standard Time | ||
+ | Asia/Tokyo en_PN Japan Standard Time | ||
+ | Asia/Tokyo en_PR Japan Standard Time | ||
+ | Asia/Tokyo en_PW Japan Standard Time | ||
+ | Asia/Tokyo en_RW Japan Standard Time | ||
+ | Asia/Tokyo en_SB Japan Standard Time | ||
+ | Asia/Tokyo en_SC Japan Standard Time | ||
+ | Asia/Tokyo en_SD Japan Standard Time | ||
+ | Asia/Tokyo en_SG Japan Standard Time | ||
+ | Asia/Tokyo en_SH Japan Standard Time | ||
+ | Asia/Tokyo en_SL Japan Standard Time | ||
+ | Asia/Tokyo en_SS Japan Standard Time | ||
+ | Asia/Tokyo en_SX Japan Standard Time | ||
+ | Asia/Tokyo en_SZ Japan Standard Time | ||
+ | Asia/Tokyo en_TC Japan Standard Time | ||
+ | Asia/Tokyo en_TK Japan Standard Time | ||
+ | Asia/Tokyo en_TO Japan Standard Time | ||
+ | Asia/Tokyo en_TT Japan Standard Time | ||
+ | Asia/Tokyo en_TV Japan Standard Time | ||
+ | Asia/Tokyo en_TZ Japan Standard Time | ||
+ | Asia/Tokyo en_UG Japan Standard Time | ||
+ | Asia/Tokyo en_UM Japan Standard Time | ||
+ | Asia/Tokyo en_US Japan Standard Time | ||
+ | Asia/Tokyo en_US_POSIX Japan Standard Time | ||
+ | Asia/Tokyo en_VC Japan Standard Time | ||
+ | Asia/Tokyo en_VG Japan Standard Time | ||
+ | Asia/Tokyo en_VI Japan Standard Time | ||
+ | Asia/Tokyo en_VU Japan Standard Time | ||
+ | Asia/Tokyo en_WS Japan Standard Time | ||
+ | Asia/Tokyo en_ZA Japan Standard Time | ||
+ | Asia/Tokyo en_ZM Japan Standard Time | ||
+ | Asia/Tokyo en_ZW Japan Standard Time | ||
+ | Asia/Tokyo eo GMT+09:00 | ||
+ | Asia/Tokyo es hora estándar de Japón | ||
+ | Asia/Tokyo es_419 hora estándar de Japón | ||
+ | Asia/Tokyo es_AR hora estándar de Japón | ||
+ | Asia/Tokyo es_BO hora estándar de Japón | ||
+ | Asia/Tokyo es_CL hora estándar de Japón | ||
+ | Asia/Tokyo es_CO hora estándar de Japón | ||
+ | Asia/Tokyo es_CR hora estándar de Japón | ||
+ | Asia/Tokyo es_CU hora estándar de Japón | ||
+ | Asia/Tokyo es_DO hora estándar de Japón | ||
+ | Asia/Tokyo es_EA hora estándar de Japón | ||
+ | Asia/Tokyo es_EC hora estándar de Japón | ||
+ | Asia/Tokyo es_ES hora estándar de Japón | ||
+ | Asia/Tokyo es_GQ hora estándar de Japón | ||
+ | Asia/Tokyo es_GT hora estándar de Japón | ||
+ | Asia/Tokyo es_HN hora estándar de Japón | ||
+ | Asia/Tokyo es_IC hora estándar de Japón | ||
+ | Asia/Tokyo es_MX Hora estándar de Japón | ||
+ | Asia/Tokyo es_NI hora estándar de Japón | ||
+ | Asia/Tokyo es_PA hora estándar de Japón | ||
+ | Asia/Tokyo es_PE hora estándar de Japón | ||
+ | Asia/Tokyo es_PH hora estándar de Japón | ||
+ | Asia/Tokyo es_PR hora estándar de Japón | ||
+ | Asia/Tokyo es_PY hora estándar de Japón | ||
+ | Asia/Tokyo es_SV hora estándar de Japón | ||
+ | Asia/Tokyo es_US hora estándar de Japón | ||
+ | Asia/Tokyo es_UY hora estándar de Japón | ||
+ | Asia/Tokyo es_VE hora estándar de Japón | ||
+ | Asia/Tokyo et Jaapani standardaeg | ||
+ | Asia/Tokyo et_EE Jaapani standardaeg | ||
+ | Asia/Tokyo eu Japoniako ordu estandarra | ||
+ | Asia/Tokyo eu_ES Japoniako ordu estandarra | ||
+ | Asia/Tokyo ewo GMT+09:00 | ||
+ | Asia/Tokyo ewo_CM GMT+09:00 | ||
+ | Asia/Tokyo fa وقت عادی ژاپن | ||
+ | Asia/Tokyo fa_AF وقت عادی ژاپن | ||
+ | Asia/Tokyo fa_IR وقت عادی ژاپن | ||
+ | Asia/Tokyo ff GMT+09:00 | ||
+ | Asia/Tokyo ff_CM GMT+09:00 | ||
+ | Asia/Tokyo ff_GN GMT+09:00 | ||
+ | Asia/Tokyo ff_MR GMT+09:00 | ||
+ | Asia/Tokyo ff_SN GMT+09:00 | ||
+ | Asia/Tokyo fi Japanin normaaliaika | ||
+ | Asia/Tokyo fi_FI Japanin normaaliaika | ||
+ | Asia/Tokyo fil Standard Time ng Japan | ||
+ | Asia/Tokyo fil_PH Standard Time ng Japan | ||
+ | Asia/Tokyo fo GMT+09:00 | ||
+ | Asia/Tokyo fo_FO GMT+09:00 | ||
+ | Asia/Tokyo fr heure normale du Japon | ||
+ | Asia/Tokyo fr_BE heure normale du Japon | ||
+ | Asia/Tokyo fr_BF heure normale du Japon | ||
+ | Asia/Tokyo fr_BI heure normale du Japon | ||
+ | Asia/Tokyo fr_BJ heure normale du Japon | ||
+ | Asia/Tokyo fr_BL heure normale du Japon | ||
+ | Asia/Tokyo fr_CA heure normale du Japon | ||
+ | Asia/Tokyo fr_CD heure normale du Japon | ||
+ | Asia/Tokyo fr_CF heure normale du Japon | ||
+ | Asia/Tokyo fr_CG heure normale du Japon | ||
+ | Asia/Tokyo fr_CH heure normale du Japon | ||
+ | Asia/Tokyo fr_CI heure normale du Japon | ||
+ | Asia/Tokyo fr_CM heure normale du Japon | ||
+ | Asia/Tokyo fr_DJ heure normale du Japon | ||
+ | Asia/Tokyo fr_DZ heure normale du Japon | ||
+ | Asia/Tokyo fr_FR heure normale du Japon | ||
+ | Asia/Tokyo fr_GA heure normale du Japon | ||
+ | Asia/Tokyo fr_GF heure normale du Japon | ||
+ | Asia/Tokyo fr_GN heure normale du Japon | ||
+ | Asia/Tokyo fr_GP heure normale du Japon | ||
+ | Asia/Tokyo fr_GQ heure normale du Japon | ||
+ | Asia/Tokyo fr_HT heure normale du Japon | ||
+ | Asia/Tokyo fr_KM heure normale du Japon | ||
+ | Asia/Tokyo fr_LU heure normale du Japon | ||
+ | Asia/Tokyo fr_MA heure normale du Japon | ||
+ | Asia/Tokyo fr_MC heure normale du Japon | ||
+ | Asia/Tokyo fr_MF heure normale du Japon | ||
+ | Asia/Tokyo fr_MG heure normale du Japon | ||
+ | Asia/Tokyo fr_ML heure normale du Japon | ||
+ | Asia/Tokyo fr_MQ heure normale du Japon | ||
+ | Asia/Tokyo fr_MR heure normale du Japon | ||
+ | Asia/Tokyo fr_MU heure normale du Japon | ||
+ | Asia/Tokyo fr_NC heure normale du Japon | ||
+ | Asia/Tokyo fr_NE heure normale du Japon | ||
+ | Asia/Tokyo fr_PF heure normale du Japon | ||
+ | Asia/Tokyo fr_PM heure normale du Japon | ||
+ | Asia/Tokyo fr_RE heure normale du Japon | ||
+ | Asia/Tokyo fr_RW heure normale du Japon | ||
+ | Asia/Tokyo fr_SC heure normale du Japon | ||
+ | Asia/Tokyo fr_SN heure normale du Japon | ||
+ | Asia/Tokyo fr_SY heure normale du Japon | ||
+ | Asia/Tokyo fr_TD heure normale du Japon | ||
+ | Asia/Tokyo fr_TG heure normale du Japon | ||
+ | Asia/Tokyo fr_TN heure normale du Japon | ||
+ | Asia/Tokyo fr_VU heure normale du Japon | ||
+ | Asia/Tokyo fr_WF heure normale du Japon | ||
+ | Asia/Tokyo fr_YT heure normale du Japon | ||
+ | Asia/Tokyo fur GMT+09:00 | ||
+ | Asia/Tokyo fur_IT GMT+09:00 | ||
+ | Asia/Tokyo fy Japanske standerttiid | ||
+ | Asia/Tokyo fy_NL Japanske standerttiid | ||
+ | Asia/Tokyo ga Am Caighdeánach na Seapáine | ||
+ | Asia/Tokyo ga_IE Am Caighdeánach na Seapáine | ||
+ | Asia/Tokyo gd Bun-àm na Seapaine | ||
+ | Asia/Tokyo gd_GB Bun-àm na Seapaine | ||
+ | Asia/Tokyo gl Horario estándar de Xapón | ||
+ | Asia/Tokyo gl_ES Horario estándar de Xapón | ||
+ | Asia/Tokyo gsw GMT+09:00 | ||
+ | Asia/Tokyo gsw_CH GMT+09:00 | ||
+ | Asia/Tokyo gsw_FR GMT+09:00 | ||
+ | Asia/Tokyo gsw_LI GMT+09:00 | ||
+ | Asia/Tokyo gu જાપાન માનક સમય | ||
+ | Asia/Tokyo gu_IN જાપાન માનક સમય | ||
+ | Asia/Tokyo guz GMT+09:00 | ||
+ | Asia/Tokyo guz_KE GMT+09:00 | ||
+ | Asia/Tokyo gv GMT+09:00 | ||
+ | Asia/Tokyo gv_IM GMT+09:00 | ||
+ | Asia/Tokyo ha GMT+09:00 | ||
+ | Asia/Tokyo ha_Latn GMT+09:00 | ||
+ | Asia/Tokyo ha_Latn_GH GMT+09:00 | ||
+ | Asia/Tokyo ha_Latn_NE GMT+09:00 | ||
+ | Asia/Tokyo ha_Latn_NG GMT+09:00 | ||
+ | Asia/Tokyo haw GMT+09:00 | ||
+ | Asia/Tokyo haw_US GMT+09:00 | ||
+ | Asia/Tokyo he שעון יפן (חורף) | ||
+ | Asia/Tokyo he_IL שעון יפן (חורף) | ||
+ | Asia/Tokyo hi जापान मानक समय | ||
+ | Asia/Tokyo hi_IN जापान मानक समय | ||
+ | Asia/Tokyo hr japansko standardno vrijeme | ||
+ | Asia/Tokyo hr_BA japansko standardno vrijeme | ||
+ | Asia/Tokyo hr_HR japansko standardno vrijeme | ||
+ | Asia/Tokyo hsb japanski standardny čas | ||
+ | Asia/Tokyo hsb_DE japanski standardny čas | ||
+ | Asia/Tokyo hu japán téli idő | ||
+ | Asia/Tokyo hu_HU japán téli idő | ||
+ | Asia/Tokyo hy Ճապոնիայի ստանդարտ ժամանակ | ||
+ | Asia/Tokyo hy_AM Ճապոնիայի ստանդարտ ժամանակ | ||
+ | Asia/Tokyo id Waktu Standar Jepang | ||
+ | Asia/Tokyo id_ID Waktu Standar Jepang | ||
+ | Asia/Tokyo ig GMT+09:00 | ||
+ | Asia/Tokyo ig_NG GMT+09:00 | ||
+ | Asia/Tokyo ii GMT+09:00 | ||
+ | Asia/Tokyo ii_CN GMT+09:00 | ||
+ | Asia/Tokyo is Staðaltími í Japan | ||
+ | Asia/Tokyo is_IS Staðaltími í Japan | ||
+ | Asia/Tokyo it Ora standard del Giappone | ||
+ | Asia/Tokyo it_CH Ora standard del Giappone | ||
+ | Asia/Tokyo it_IT Ora standard del Giappone | ||
+ | Asia/Tokyo it_SM Ora standard del Giappone | ||
+ | Asia/Tokyo ja 日本標準時 | ||
+ | Asia/Tokyo ja_JP 日本標準時 | ||
+ | Asia/Tokyo jgo GMT+09:00 | ||
+ | Asia/Tokyo jgo_CM GMT+09:00 | ||
+ | Asia/Tokyo jmc GMT+09:00 | ||
+ | Asia/Tokyo jmc_TZ GMT+09:00 | ||
+ | Asia/Tokyo ka იაპონიის სტანდარტული დრო | ||
+ | Asia/Tokyo ka_GE იაპონიის სტანდარტული დრო | ||
+ | Asia/Tokyo kab GMT+09:00 | ||
+ | Asia/Tokyo kab_DZ GMT+09:00 | ||
+ | Asia/Tokyo kam GMT+09:00 | ||
+ | Asia/Tokyo kam_KE GMT+09:00 | ||
+ | Asia/Tokyo kde GMT+09:00 | ||
+ | Asia/Tokyo kde_TZ GMT+09:00 | ||
+ | Asia/Tokyo kea GMT+09:00 | ||
+ | Asia/Tokyo kea_CV GMT+09:00 | ||
+ | Asia/Tokyo khq GMT+09:00 | ||
+ | Asia/Tokyo khq_ML GMT+09:00 | ||
+ | Asia/Tokyo ki GMT+09:00 | ||
+ | Asia/Tokyo ki_KE GMT+09:00 | ||
+ | Asia/Tokyo kk Жапония стандартты уақыты | ||
+ | Asia/Tokyo kk_Cyrl Жапония стандартты уақыты | ||
+ | Asia/Tokyo kk_Cyrl_KZ Жапония стандартты уақыты | ||
+ | Asia/Tokyo kkj GMT+09:00 | ||
+ | Asia/Tokyo kkj_CM GMT+09:00 | ||
+ | Asia/Tokyo kl GMT+09:00 | ||
+ | Asia/Tokyo kl_GL GMT+09:00 | ||
+ | Asia/Tokyo kln GMT+09:00 | ||
+ | Asia/Tokyo kln_KE GMT+09:00 | ||
+ | Asia/Tokyo km ម៉ោងស្តង់ដារនៅជប៉ុន | ||
+ | Asia/Tokyo km_KH ម៉ោងស្តង់ដារនៅជប៉ុន | ||
+ | Asia/Tokyo kn ಜಪಾನ್ ಪ್ರಮಾಣಿತ ಸಮಯ | ||
+ | Asia/Tokyo kn_IN ಜಪಾನ್ ಪ್ರಮಾಣಿತ ಸಮಯ | ||
+ | Asia/Tokyo ko 일본 표준시 | ||
+ | Asia/Tokyo ko_KP 일본 표준시 | ||
+ | Asia/Tokyo ko_KR 일본 표준시 | ||
+ | Asia/Tokyo kok GMT+09:00 | ||
+ | Asia/Tokyo kok_IN GMT+09:00 | ||
+ | Asia/Tokyo ks جاپٲنۍ سٹینڑاڑ ٹایِم | ||
+ | Asia/Tokyo ks_Arab جاپٲنۍ سٹینڑاڑ ٹایِم | ||
+ | Asia/Tokyo ks_Arab_IN جاپٲنۍ سٹینڑاڑ ٹایِم | ||
+ | Asia/Tokyo ksb GMT+09:00 | ||
+ | Asia/Tokyo ksb_TZ GMT+09:00 | ||
+ | Asia/Tokyo ksf GMT+09:00 | ||
+ | Asia/Tokyo ksf_CM GMT+09:00 | ||
+ | Asia/Tokyo ksh GMT+09:00 | ||
+ | Asia/Tokyo ksh_DE GMT+09:00 | ||
+ | Asia/Tokyo kw GMT+09:00 | ||
+ | Asia/Tokyo kw_GB GMT+09:00 | ||
+ | Asia/Tokyo ky Жапан стандарт убактысы | ||
+ | Asia/Tokyo ky_Cyrl Жапан стандарт убактысы | ||
+ | Asia/Tokyo ky_Cyrl_KG Жапан стандарт убактысы | ||
+ | Asia/Tokyo lag GMT+09:00 | ||
+ | Asia/Tokyo lag_TZ GMT+09:00 | ||
+ | Asia/Tokyo lb Japanesch Normalzäit | ||
+ | Asia/Tokyo lb_LU Japanesch Normalzäit | ||
+ | Asia/Tokyo lg GMT+09:00 | ||
+ | Asia/Tokyo lg_UG GMT+09:00 | ||
+ | Asia/Tokyo lkt GMT+09:00 | ||
+ | Asia/Tokyo lkt_US GMT+09:00 | ||
+ | Asia/Tokyo ln GMT+09:00 | ||
+ | Asia/Tokyo ln_AO GMT+09:00 | ||
+ | Asia/Tokyo ln_CD GMT+09:00 | ||
+ | Asia/Tokyo ln_CF GMT+09:00 | ||
+ | Asia/Tokyo ln_CG GMT+09:00 | ||
+ | Asia/Tokyo lo ເວລາມາດຕະຖານຍີ່ປຸ່ນ | ||
+ | Asia/Tokyo lo_LA ເວລາມາດຕະຖານຍີ່ປຸ່ນ | ||
+ | Asia/Tokyo lt Japonijos žiemos laikas | ||
+ | Asia/Tokyo lt_LT Japonijos žiemos laikas | ||
+ | Asia/Tokyo lu GMT+09:00 | ||
+ | Asia/Tokyo lu_CD GMT+09:00 | ||
+ | Asia/Tokyo luo GMT+09:00 | ||
+ | Asia/Tokyo luo_KE GMT+09:00 | ||
+ | Asia/Tokyo luy GMT+09:00 | ||
+ | Asia/Tokyo luy_KE GMT+09:00 | ||
+ | Asia/Tokyo lv Japānas ziemas laiks | ||
+ | Asia/Tokyo lv_LV Japānas ziemas laiks | ||
+ | Asia/Tokyo mas GMT+09:00 | ||
+ | Asia/Tokyo mas_KE GMT+09:00 | ||
+ | Asia/Tokyo mas_TZ GMT+09:00 | ||
+ | Asia/Tokyo mer GMT+09:00 | ||
+ | Asia/Tokyo mer_KE GMT+09:00 | ||
+ | Asia/Tokyo mfe GMT+09:00 | ||
+ | Asia/Tokyo mfe_MU GMT+09:00 | ||
+ | Asia/Tokyo mg GMT+09:00 | ||
+ | Asia/Tokyo mg_MG GMT+09:00 | ||
+ | Asia/Tokyo mgh GMT+09:00 | ||
+ | Asia/Tokyo mgh_MZ GMT+09:00 | ||
+ | Asia/Tokyo mgo GMT+09:00 | ||
+ | Asia/Tokyo mgo_CM GMT+09:00 | ||
+ | Asia/Tokyo mk Стандардно време во Јапонија | ||
+ | Asia/Tokyo mk_MK Стандардно време во Јапонија | ||
+ | Asia/Tokyo ml ജപ്പാൻ സ്റ്റാൻഡേർഡ് സമയം | ||
+ | Asia/Tokyo ml_IN ജപ്പാൻ സ്റ്റാൻഡേർഡ് സമയം | ||
+ | Asia/Tokyo mn Японы стандарт цаг | ||
+ | Asia/Tokyo mn_Cyrl Японы стандарт цаг | ||
+ | Asia/Tokyo mn_Cyrl_MN Японы стандарт цаг | ||
+ | Asia/Tokyo mr जपान प्रमाण वेळ | ||
+ | Asia/Tokyo mr_IN जपान प्रमाण वेळ | ||
+ | Asia/Tokyo ms Waktu Piawai Jepun | ||
+ | Asia/Tokyo ms_Latn Waktu Piawai Jepun | ||
+ | Asia/Tokyo ms_Latn_BN Waktu Piawai Jepun | ||
+ | Asia/Tokyo ms_Latn_MY Waktu Piawai Jepun | ||
+ | Asia/Tokyo ms_Latn_SG Waktu Piawai Jepun | ||
+ | Asia/Tokyo mt GMT+09:00 | ||
+ | Asia/Tokyo mt_MT GMT+09:00 | ||
+ | Asia/Tokyo mua GMT+09:00 | ||
+ | Asia/Tokyo mua_CM GMT+09:00 | ||
+ | Asia/Tokyo my ဂျပန် စံတော်ချိန် | ||
+ | Asia/Tokyo my_MM ဂျပန် စံတော်ချိန် | ||
+ | Asia/Tokyo naq GMT+09:00 | ||
+ | Asia/Tokyo naq_NA GMT+09:00 | ||
+ | Asia/Tokyo nb japansk normaltid | ||
+ | Asia/Tokyo nb_NO japansk normaltid | ||
+ | Asia/Tokyo nb_SJ japansk normaltid | ||
+ | Asia/Tokyo nd GMT+09:00 | ||
+ | Asia/Tokyo nd_ZW GMT+09:00 | ||
+ | Asia/Tokyo ne जापान मानक समय | ||
+ | Asia/Tokyo ne_IN जापान मानक समय | ||
+ | Asia/Tokyo ne_NP जापान मानक समय | ||
+ | Asia/Tokyo nl Japanse standaardtijd | ||
+ | Asia/Tokyo nl_AW Japanse standaardtijd | ||
+ | Asia/Tokyo nl_BE Japanse standaardtijd | ||
+ | Asia/Tokyo nl_BQ Japanse standaardtijd | ||
+ | Asia/Tokyo nl_CW Japanse standaardtijd | ||
+ | Asia/Tokyo nl_NL Japanse standaardtijd | ||
+ | Asia/Tokyo nl_SR Japanse standaardtijd | ||
+ | Asia/Tokyo nl_SX Japanse standaardtijd | ||
+ | Asia/Tokyo nmg GMT+09:00 | ||
+ | Asia/Tokyo nmg_CM GMT+09:00 | ||
+ | Asia/Tokyo nn GMT+09:00 | ||
+ | Asia/Tokyo nn_NO GMT+09:00 | ||
+ | Asia/Tokyo nnh GMT+09:00 | ||
+ | Asia/Tokyo nnh_CM GMT+09:00 | ||
+ | Asia/Tokyo nus GMT+09:00 | ||
+ | Asia/Tokyo nus_SD GMT+09:00 | ||
+ | Asia/Tokyo nyn GMT+09:00 | ||
+ | Asia/Tokyo nyn_UG GMT+09:00 | ||
+ | Asia/Tokyo om GMT+09:00 | ||
+ | Asia/Tokyo om_ET GMT+09:00 | ||
+ | Asia/Tokyo om_KE GMT+09:00 | ||
+ | Asia/Tokyo or GMT+09:00 | ||
+ | Asia/Tokyo or_IN GMT+09:00 | ||
+ | Asia/Tokyo os GMT+09:00 | ||
+ | Asia/Tokyo os_GE GMT+09:00 | ||
+ | Asia/Tokyo os_RU GMT+09:00 | ||
+ | Asia/Tokyo pa ਜਪਾਨ ਮਿਆਰੀ ਸਮਾਂ | ||
+ | Asia/Tokyo pa_Arab GMT+۰۹:۰۰ | ||
+ | Asia/Tokyo pa_Arab_PK GMT+۰۹:۰۰ | ||
+ | Asia/Tokyo pa_Guru ਜਪਾਨ ਮਿਆਰੀ ਸਮਾਂ | ||
+ | Asia/Tokyo pa_Guru_IN ਜਪਾਨ ਮਿਆਰੀ ਸਮਾਂ | ||
+ | Asia/Tokyo pl Japonia (czas standardowy) | ||
+ | Asia/Tokyo pl_PL Japonia (czas standardowy) | ||
+ | Asia/Tokyo ps GMT+۰۹:۰۰ | ||
+ | Asia/Tokyo ps_AF GMT+۰۹:۰۰ | ||
+ | Asia/Tokyo pt Horário Padrão do Japão | ||
+ | Asia/Tokyo pt_AO Hora Padrão do Japão | ||
+ | Asia/Tokyo pt_BR Horário Padrão do Japão | ||
+ | Asia/Tokyo pt_CV Hora Padrão do Japão | ||
+ | Asia/Tokyo pt_GW Hora Padrão do Japão | ||
+ | Asia/Tokyo pt_MO Hora Padrão do Japão | ||
+ | Asia/Tokyo pt_MZ Hora Padrão do Japão | ||
+ | Asia/Tokyo pt_PT Hora Padrão do Japão | ||
+ | Asia/Tokyo pt_ST Hora Padrão do Japão | ||
+ | Asia/Tokyo pt_TL Hora Padrão do Japão | ||
+ | Asia/Tokyo qu GMT+09:00 | ||
+ | Asia/Tokyo qu_BO GMT+09:00 | ||
+ | Asia/Tokyo qu_EC GMT+09:00 | ||
+ | Asia/Tokyo qu_PE GMT+09:00 | ||
+ | Asia/Tokyo rm GMT+09:00 | ||
+ | Asia/Tokyo rm_CH GMT+09:00 | ||
+ | Asia/Tokyo rn GMT+09:00 | ||
+ | Asia/Tokyo rn_BI GMT+09:00 | ||
+ | Asia/Tokyo ro Ora standard a Japoniei | ||
+ | Asia/Tokyo ro_MD Ora standard a Japoniei | ||
+ | Asia/Tokyo ro_RO Ora standard a Japoniei | ||
+ | Asia/Tokyo rof GMT+09:00 | ||
+ | Asia/Tokyo rof_TZ GMT+09:00 | ||
+ | Asia/Tokyo ru Япония, стандартное время | ||
+ | Asia/Tokyo ru_BY Япония, стандартное время | ||
+ | Asia/Tokyo ru_KG Япония, стандартное время | ||
+ | Asia/Tokyo ru_KZ Япония, стандартное время | ||
+ | Asia/Tokyo ru_MD Япония, стандартное время | ||
+ | Asia/Tokyo ru_RU Япония, стандартное время | ||
+ | Asia/Tokyo ru_UA Япония, стандартное время | ||
+ | Asia/Tokyo rw GMT+09:00 | ||
+ | Asia/Tokyo rw_RW GMT+09:00 | ||
+ | Asia/Tokyo rwk GMT+09:00 | ||
+ | Asia/Tokyo rwk_TZ GMT+09:00 | ||
+ | Asia/Tokyo sah GMT+09:00 | ||
+ | Asia/Tokyo sah_RU GMT+09:00 | ||
+ | Asia/Tokyo saq GMT+09:00 | ||
+ | Asia/Tokyo saq_KE GMT+09:00 | ||
+ | Asia/Tokyo sbp GMT+09:00 | ||
+ | Asia/Tokyo sbp_TZ GMT+09:00 | ||
+ | Asia/Tokyo se UTC+09:00 | ||
+ | Asia/Tokyo se_FI UTC+09:00 | ||
+ | Asia/Tokyo se_NO UTC+09:00 | ||
+ | Asia/Tokyo se_SE UTC+09:00 | ||
+ | Asia/Tokyo seh GMT+09:00 | ||
+ | Asia/Tokyo seh_MZ GMT+09:00 | ||
+ | Asia/Tokyo ses GMT+09:00 | ||
+ | Asia/Tokyo ses_ML GMT+09:00 | ||
+ | Asia/Tokyo sg GMT+09:00 | ||
+ | Asia/Tokyo sg_CF GMT+09:00 | ||
+ | Asia/Tokyo shi GMT+09:00 | ||
+ | Asia/Tokyo shi_Latn GMT+09:00 | ||
+ | Asia/Tokyo shi_Latn_MA GMT+09:00 | ||
+ | Asia/Tokyo shi_Tfng GMT+09:00 | ||
+ | Asia/Tokyo shi_Tfng_MA GMT+09:00 | ||
+ | Asia/Tokyo si ජපාන සම්මත වේලාව | ||
+ | Asia/Tokyo si_LK ජපාන සම්මත වේලාව | ||
+ | Asia/Tokyo sk Japonský štandardný čas | ||
+ | Asia/Tokyo sk_SK Japonský štandardný čas | ||
+ | Asia/Tokyo sl Japonski standardni čas | ||
+ | Asia/Tokyo sl_SI Japonski standardni čas | ||
+ | Asia/Tokyo smn GMT+09:00 | ||
+ | Asia/Tokyo smn_FI GMT+09:00 | ||
+ | Asia/Tokyo sn GMT+09:00 | ||
+ | Asia/Tokyo sn_ZW GMT+09:00 | ||
+ | Asia/Tokyo so GMT+09:00 | ||
+ | Asia/Tokyo so_DJ GMT+09:00 | ||
+ | Asia/Tokyo so_ET GMT+09:00 | ||
+ | Asia/Tokyo so_KE GMT+09:00 | ||
+ | Asia/Tokyo so_SO GMT+09:00 | ||
+ | Asia/Tokyo sq Ora standarde e Japonisë | ||
+ | Asia/Tokyo sq_AL Ora standarde e Japonisë | ||
+ | Asia/Tokyo sq_MK Ora standarde e Japonisë | ||
+ | Asia/Tokyo sq_XK Ora standarde e Japonisë | ||
+ | Asia/Tokyo sr Јапанско стандардно време | ||
+ | Asia/Tokyo sr_Cyrl Јапанско стандардно време | ||
+ | Asia/Tokyo sr_Cyrl_BA Јапанско стандардно време | ||
+ | Asia/Tokyo sr_Cyrl_ME Јапанско стандардно време | ||
+ | Asia/Tokyo sr_Cyrl_RS Јапанско стандардно време | ||
+ | Asia/Tokyo sr_Cyrl_XK Јапанско стандардно време | ||
+ | Asia/Tokyo sr_Latn Japansko standardno vreme | ||
+ | Asia/Tokyo sr_Latn_BA Japansko standardno vreme | ||
+ | Asia/Tokyo sr_Latn_ME Japansko standardno vreme | ||
+ | Asia/Tokyo sr_Latn_RS Japansko standardno vreme | ||
+ | Asia/Tokyo sr_Latn_XK Japansko standardno vreme | ||
+ | Asia/Tokyo sv japansk normaltid | ||
+ | Asia/Tokyo sv_AX japansk normaltid | ||
+ | Asia/Tokyo sv_FI japansk normaltid | ||
+ | Asia/Tokyo sv_SE japansk normaltid | ||
+ | Asia/Tokyo sw Saa Wastani za Japani | ||
+ | Asia/Tokyo sw_KE Saa Wastani za Japani | ||
+ | Asia/Tokyo sw_TZ Saa Wastani za Japani | ||
+ | Asia/Tokyo sw_UG Saa Wastani za Japani | ||
+ | Asia/Tokyo swc GMT+09:00 | ||
+ | Asia/Tokyo swc_CD GMT+09:00 | ||
+ | Asia/Tokyo ta ஜப்பான் நிலையான நேரம் | ||
+ | Asia/Tokyo ta_IN ஜப்பான் நிலையான நேரம் | ||
+ | Asia/Tokyo ta_LK ஜப்பான் நிலையான நேரம் | ||
+ | Asia/Tokyo ta_MY ஜப்பான் நிலையான நேரம் | ||
+ | Asia/Tokyo ta_SG ஜப்பான் நிலையான நேரம் | ||
+ | Asia/Tokyo te జపాన్ ప్రామాణిక సమయం | ||
+ | Asia/Tokyo te_IN జపాన్ ప్రామాణిక సమయం | ||
+ | Asia/Tokyo teo GMT+09:00 | ||
+ | Asia/Tokyo teo_KE GMT+09:00 | ||
+ | Asia/Tokyo teo_UG GMT+09:00 | ||
+ | Asia/Tokyo th เวลามาตรฐานญี่ปุ่น | ||
+ | Asia/Tokyo th_TH เวลามาตรฐานญี่ปุ่น | ||
+ | Asia/Tokyo ti GMT+09:00 | ||
+ | Asia/Tokyo ti_ER GMT+09:00 | ||
+ | Asia/Tokyo ti_ET GMT+09:00 | ||
+ | Asia/Tokyo to houa fakasiapani taimi totonu | ||
+ | Asia/Tokyo to_TO houa fakasiapani taimi totonu | ||
+ | Asia/Tokyo tr Japonya Standart Saati | ||
+ | Asia/Tokyo tr_CY Japonya Standart Saati | ||
+ | Asia/Tokyo tr_TR Japonya Standart Saati | ||
+ | Asia/Tokyo twq GMT+09:00 | ||
+ | Asia/Tokyo twq_NE GMT+09:00 | ||
+ | Asia/Tokyo tzm GMT+09:00 | ||
+ | Asia/Tokyo tzm_Latn GMT+09:00 | ||
+ | Asia/Tokyo tzm_Latn_MA GMT+09:00 | ||
+ | Asia/Tokyo ug ياپونىيە ئۆلچەملىك ۋاقتى | ||
+ | Asia/Tokyo ug_Arab ياپونىيە ئۆلچەملىك ۋاقتى | ||
+ | Asia/Tokyo ug_Arab_CN ياپونىيە ئۆلچەملىك ۋاقتى | ||
+ | Asia/Tokyo uk за японським стандартним часом | ||
+ | Asia/Tokyo uk_UA за японським стандартним часом | ||
+ | Asia/Tokyo ur جاپان سٹینڈرڈ ٹائم | ||
+ | Asia/Tokyo ur_IN جاپان سٹینڈرڈ ٹائم | ||
+ | Asia/Tokyo ur_PK جاپان سٹینڈرڈ ٹائم | ||
+ | Asia/Tokyo uz Yaponiya standart vaqti | ||
+ | Asia/Tokyo uz_Arab GMT+۰۹:۰۰ | ||
+ | Asia/Tokyo uz_Arab_AF GMT+۰۹:۰۰ | ||
+ | Asia/Tokyo uz_Cyrl Япония стандарт вақти | ||
+ | Asia/Tokyo uz_Cyrl_UZ Япония стандарт вақти | ||
+ | Asia/Tokyo uz_Latn Yaponiya standart vaqti | ||
+ | Asia/Tokyo uz_Latn_UZ Yaponiya standart vaqti | ||
+ | Asia/Tokyo vai GMT+09:00 | ||
+ | Asia/Tokyo vai_Latn GMT+09:00 | ||
+ | Asia/Tokyo vai_Latn_LR GMT+09:00 | ||
+ | Asia/Tokyo vai_Vaii GMT+09:00 | ||
+ | Asia/Tokyo vai_Vaii_LR GMT+09:00 | ||
+ | Asia/Tokyo vi Giờ Chuẩn Nhật Bản | ||
+ | Asia/Tokyo vi_VN Giờ Chuẩn Nhật Bản | ||
+ | Asia/Tokyo vun GMT+09:00 | ||
+ | Asia/Tokyo vun_TZ GMT+09:00 | ||
+ | Asia/Tokyo wae GMT+09:00 | ||
+ | Asia/Tokyo wae_CH GMT+09:00 | ||
+ | Asia/Tokyo xog GMT+09:00 | ||
+ | Asia/Tokyo xog_UG GMT+09:00 | ||
+ | Asia/Tokyo yav GMT+09:00 | ||
+ | Asia/Tokyo yav_CM GMT+09:00 | ||
+ | Asia/Tokyo yi GMT+09:00 | ||
+ | Asia/Tokyo yi_001 GMT+09:00 | ||
+ | Asia/Tokyo yo GMT+09:00 | ||
+ | Asia/Tokyo yo_BJ GMT+09:00 | ||
+ | Asia/Tokyo yo_NG GMT+09:00 | ||
+ | Asia/Tokyo zgh GMT+09:00 | ||
+ | Asia/Tokyo zgh_MA GMT+09:00 | ||
+ | Asia/Tokyo zh 日本标准时间 | ||
+ | Asia/Tokyo zh_Hans 日本标准时间 | ||
+ | Asia/Tokyo zh_Hans_CN 日本标准时间 | ||
+ | Asia/Tokyo zh_Hans_HK 日本标准时间 | ||
+ | Asia/Tokyo zh_Hans_MO 日本标准时间 | ||
+ | Asia/Tokyo zh_Hans_SG 日本标准时间 | ||
+ | Asia/Tokyo zh_Hant 日本標準時間 | ||
+ | Asia/Tokyo zh_Hant_HK 日本標準時間 | ||
+ | Asia/Tokyo zh_Hant_MO 日本標準時間 | ||
+ | Asia/Tokyo zh_Hant_TW 日本標準時間 | ||
+ | Asia/Tokyo zu Isikhathi esivamile sase-Japan | ||
+ | Asia/Tokyo zu_ZA Isikhathi esivamile sase-Japan | ||
+ | </syntaxhighlight2> | ||
+ | |||
+ | =='''文字列の抽出'''== | ||
+ | 文字列のコピーでコピーする文字数を限定する関数***ncpy系の関数がありましたので、前方抽出はできまるようになったと思います。他にもtokenを使ったり、正規表現を使う事でも抽出ができました。これらの文字の位置を示す関数と、この他にも存在する文字の位置に関する関数を活用することで、もっと他の抽出方法を考えることもできます。前方から何文字目~n文字。前方のnバイト目に目的の文字開始位置があれば、そこからn文字、前方のnバイト目に目的の文字開始位置があって、次のmバイト目に終端位置があって、その間にあるn文字を抽出といった具合です。これらはマルチバイト文字がおさめられた文字列変数ではバイト数と文字数が一致しないことから慎重に処理する必要があります。またワイド文字も2バイト固定のように感じてしまいますが、実際は4バイトの文字である可能性も0ではないので、きちんと文字数とバイト数を計算して、開始位置に文字型ポインターを格納したりする必要があります。配列によって決まった長さの実体のある文字列で終端に\0が入っているような構造の先頭を指し示すポインタと、そのポインタの型と同じだけど実体は持たないポインタの変数を利用して、実体を持たないポインタ変数が、文字の抽出開始位置を指し示すようにすること、そこらからコピーする文字数を正確に数えることがポイントになります。ポイントというとポインタと紛らわしいので、ミソになりますとでも言った方がいいのかもしれません。ここで紹介する抽出と、これまでに紹介した正規表現やtokenを活用すると更に操作の幅が広がります。 | ||
+ | |||
+ | |||
+ | とにかく文字を数えて、文字列ポインタを移動させ、サロゲートペアなら4バイト、通常のワイド文字範囲なら2byteってなかんじで数えます。面倒ですが、サロゲートペアのことを考えると文字数での抽出はこのような気遣いが必要です。マルチバイト文字でやるときは、また違った対応が必要になります。仕組みとしては文字数とバイト数をきちんと数えて、先頭文字にポインタを合わせる。***ncpy系の関数でそこから必要なバイト数をコピーするという感じになります。コンソール画面ではShiftJISなので文字化けしますから、Unicode文字としてテキストに出力するプログラムになっています。今回のプログラムでは対応しませんでしたが、異体字セレクタに対応すると、2バイト文字にはさらに DB40 DD00 の4バイトが付与されていますので、次の4バイトの値がDB40 DD**になっていないか確認をする必要があり、そのようになっている場合は+4バイトするような計算も必要です。テキストエディタを作成する場合にはフォントを異体字セレクタにしたがって切り替える試みが必要になります。フォントが対応していなければ切り替えることはできないので、処理としては元の文字を表示するだけになります。DB40 DD** のような異体字補助番号は文字コードとして使われないことになっています。 | ||
+ | <syntaxhighlight2 lang="cpp" line start="1"> | ||
+ | #pragma once | ||
+ | #include "stdafx.h" | ||
+ | #include <stdlib.h> | ||
+ | #include <string> //std::string型定義 | ||
+ | #include <mbstring.h> //mbs***関数 | ||
+ | #include <iostream> //cpp cout etc 一般入出力関数 | ||
+ | #include <locale> //Locale関数 | ||
+ | #include <tchar.h> //TCHAR型+_tcs***関数 | ||
+ | #include "atlstr.h" //CString,CStringA,CStringWおよびLPTSTR,LPWSTR,LPSTR,LPCTSTR,LPCWSTR,LPCSTRの定義プリプロセッサ | ||
+ | #include "atlbase.h" //同上 | ||
+ | #include "cstringt.h" //CStringTの定義プリプロセッサ | ||
+ | #include <vector> //Vector型テンプレートクラス | ||
+ | |||
+ | #include <sys/timeb.h> //Timeb型構造体 | ||
+ | |||
+ | //_bstr_t型を利用するプリプロセッサ(ライブラリはデバッグモードとリリースモード個別設定) | ||
+ | #include "comutil.h" | ||
+ | |||
+ | #ifdef _DEBUG | ||
+ | #pragma comment(lib, "comsuppwd.lib") | ||
+ | #else | ||
+ | #pragma comment(lib, "comsuppw.lib") | ||
+ | #endif | ||
+ | //_bstr_t _End | ||
+ | |||
+ | //ICU ucnvプリプロセッサ(ライブラリはデバッグモードとリリースモード個別設定) | ||
+ | #include <unicode/ucnv.h> //ucnv文字コード変換ライブラリヘッダ | ||
+ | #include <unicode/translit.h> //文字変換ライブラリヘッダ | ||
+ | #include <unicode/regex.h> //正規表現 | ||
+ | #include <unicode/ucsdet.h> //文字コード判定 | ||
+ | #include <unicode/ucal.h> //文字コード判定 | ||
+ | #include <unicode/uclean.h> //u_cleanup関数 | ||
+ | /* for uloc_getDefault() */ | ||
+ | #include <unicode/uloc.h> | ||
+ | #include <unicode/calendar.h> | ||
+ | #include <unicode/smpdtfmt.h> | ||
+ | |||
+ | //#include "unicode/utypes.h" | ||
+ | //#include "unicode/locid.h" | ||
+ | //#include "unicode/unistr.h" | ||
+ | //#include "unicode/tzfmt.h" | ||
+ | //#include "unicode/tznames.h" | ||
+ | |||
+ | |||
+ | #ifdef _DEBUG | ||
+ | #pragma comment(lib, "icudt.lib") | ||
+ | #pragma comment(lib, "icuucd.lib") //ICU ucnvを使うために必要なライブラリ | ||
+ | #pragma comment(lib, "icuind.lib") //ICU Transliterate関数を使うために必要なライブラリ 正規表現関数も | ||
+ | #pragma comment(lib, "iculed.lib") | ||
+ | #pragma comment(lib, "iculxd.lib") | ||
+ | #pragma comment(lib, "icuiod.lib") | ||
+ | #pragma comment(lib, "icutud.lib") | ||
+ | |||
+ | #else | ||
+ | //#pragma comment(lib, "icudt.lib") | ||
+ | #pragma comment(lib, "icuind.lib") //ICU Transliterate関数を使うために必要なライブラリ 正規表現関数も | ||
+ | #pragma comment(lib, "icuuc.lib") //ICU ucnvを使うために必要なライブラリ | ||
+ | //#pragma comment(lib, "icuio.lib") | ||
+ | #endif | ||
+ | //Data Library icudtXX(d).dll icudt(d).lib | ||
+ | //Common Library icuucXX(d).dll icuuc(d).lib | ||
+ | //Internationalization(i18n) Library icuinXX(d).dll icuin(d).lib | ||
+ | //Layout Engine iculeXX(d).dll icule(d).lib | ||
+ | //Layout Extention Engine iculxXX(d).dll iculx(d).lib | ||
+ | //ICU I/O(Unicode stdio) Library icuioXX(d).dll icuio(d).lib | ||
+ | //Tool Utility Library icutuXX(d).dll icutu(d).lib | ||
+ | |||
+ | //ICU ucnv _End | ||
+ | |||
+ | #include "UnicodeConverter.h" | ||
+ | |||
+ | using namespace std; | ||
+ | |||
+ | int _tmain(int argc, _TCHAR* argv[]) | ||
+ | { | ||
+ | _tsetlocale(LC_ALL, _T("Japanese")); //ロケールセットすると_l関数でロケール指定しなくても日本語が使われます。 | ||
+ | |||
+ | _locale_t localeJpanease; | ||
+ | localeJpanease = _create_locale(LC_ALL, "Japanese"); | ||
+ | |||
+ | FILE* pfileText; | ||
+ | fpos_t* fposPos = new fpos_t; | ||
+ | errno_t errNo; | ||
+ | size_t* psizeRuturnValue = new size_t; | ||
+ | |||
+ | wchar_t pwcStrFilePath[] = L"C:\\...\\...\\...\\test_new_Extract.txt"; | ||
+ | char* pcStrStream; | ||
+ | pcStrStream = new char[1024]; | ||
+ | int nCloseResult = 0; | ||
+ | |||
+ | wchar_t pwcStrSurrogate[] = L"\xD840\xDC0B\xD867\xDE3Dごはん\xD840\xDC0B\xD842\xDFB7を食べたYo。";//L"𠀋𩸽ごはん𠀋𠮷を食べたYo。"と同じ。 | ||
+ | const wchar_t* pwcStrPos;//実体は持たない文字位置格納変数 | ||
+ | const wchar_t* pwcStrStPos;//実体は持たない文字位置格納変数 | ||
+ | wchar_t* pwcStrSurrogateExtract; | ||
+ | |||
+ | pwcStrPos = pwcStrSurrogate; | ||
+ | int nSize = wcslen(pwcStrSurrogate); | ||
+ | int nByteCnt = 0; | ||
+ | int nCharCnt = 0; | ||
+ | int nStPos = 2;//文字位置では0文字目からカウントする仕組みなので、3文字目にポインタが合います。 | ||
+ | printf("%d\n",nSize); | ||
+ | while (nByteCnt < nSize && nCharCnt < nStPos){ | ||
+ | unsigned int unValue = _wcsnextc(pwcStrPos); | ||
+ | pwcStrPos++; | ||
+ | printf("%0x:",unValue); | ||
+ | if(unValue >= 0xD800 && unValue <= 0xDFFF){ | ||
+ | pwcStrPos++; | ||
+ | nByteCnt++; | ||
+ | } | ||
+ | nCharCnt++; | ||
+ | nByteCnt++; | ||
+ | } | ||
+ | pwcStrStPos = pwcStrPos;//先頭の文字列にポインタを合わせる。 | ||
+ | printf("\n"); | ||
+ | printf("%d[Byte],%d[文字]\n",nByteCnt,nCharCnt); | ||
+ | int nEnPos = 5;//先頭文字から5文字目までのバイト数を数えます。そういう意味では最初の先頭文字の指定と合わせた方が良かったかも。 | ||
+ | nByteCnt = 0; | ||
+ | nCharCnt = 0; | ||
+ | nSize = wcslen(pwcStrPos); | ||
+ | |||
+ | printf("%d\n",nSize); | ||
+ | while (nByteCnt < nSize && nCharCnt < nEnPos){ | ||
+ | unsigned int unValue = _wcsnextc(pwcStrPos); | ||
+ | pwcStrPos++; | ||
+ | printf("%0x:",unValue); | ||
+ | if(unValue >= 0xD800 && unValue <= 0xDFFF){ | ||
+ | pwcStrPos++; | ||
+ | nByteCnt++; | ||
+ | } | ||
+ | nCharCnt++; | ||
+ | nByteCnt++; | ||
+ | } | ||
+ | printf("\n"); | ||
+ | |||
+ | pwcStrSurrogateExtract = new wchar_t[nByteCnt + 1]; | ||
+ | wcsncpy_s(pwcStrSurrogateExtract, nByteCnt + 1, pwcStrStPos, nByteCnt);//5文字分のバイト数をコピーする。7バイトだね。 | ||
+ | |||
+ | printf("%d[Byte],%d[文字]\n",nByteCnt,nCharCnt); | ||
+ | wprintf(L"%s",pwcStrPos); | ||
+ | printf("\n"); | ||
+ | |||
+ | fpos_t* pfposStartPos = new fpos_t; | ||
+ | printf("★テキストの新規書き込み\n"); | ||
+ | errNo = _wfopen_s( &pfileText, pwcStrFilePath, L"w,ccs=UTF-16LE"); | ||
+ | printf("Error?->%d\n", errNo); | ||
+ | |||
+ | fputws(pwcStrSurrogate,pfileText); | ||
+ | fputws(L"\n",pfileText); | ||
+ | |||
+ | fputws(pwcStrStPos,pfileText); | ||
+ | fputws(L"\n",pfileText); | ||
+ | |||
+ | fputws(pwcStrPos,pfileText); | ||
+ | fputws(L"\n",pfileText); | ||
+ | |||
+ | fputws(pwcStrSurrogateExtract,pfileText); | ||
+ | |||
+ | fclose(pfileText); | ||
+ | return 0; | ||
+ | } | ||
+ | </syntaxhighlight2> | ||
+ | コンソール側出力 | ||
+ | <syntaxhighlight2 lang="text"> | ||
+ | 18 | ||
+ | d840:d842: | ||
+ | 4[Byte],2[文字] | ||
+ | 14 | ||
+ | 3054:306f:3093:d840:d842: | ||
+ | 7[Byte],5[文字] | ||
+ | を食べたYo。 | ||
+ | ★テキストの新規書き込み | ||
+ | Error?->0 | ||
+ | </syntaxhighlight2> | ||
+ | テキスト出力 | ||
+ | <syntaxhighlight2 lang="text"> | ||
+ | 𠀋𩸽ごはん𠀋𠮷を食べたYo。 | ||
+ | ごはん𠀋𠮷を食べたYo。 | ||
+ | を食べたYo。 | ||
+ | ごはん𠀋𠮷 | ||
+ | </syntaxhighlight2> | ||
+ | |||
+ | |||
+ | という感じで、以上ですかね。 | ||
+ | |||
+ | |||
+ | 基本機能を用いて、文字列操作のすべてを掌握できるような、異常なまでに長い記事を書いたつもりです。それくらい文字列操作はコンピュータを使う人から喜ばれるプログラミングだと思います。文字を扱うプログラムは意思を疎通したり記録したり、人間文化の中枢にある処理です。プログラムによって文字情報をうまく表示してくれたり、編集してくれたり、閲覧できるようになることは、ありがたいこと、この上ない機能でしょう。ここで紹介したものだけでは文字処理の効率はイマイチかもしれません。便利な文字列クラスはこのWebの世界をたぐり探せば存在するかもしれません。ですが、C++範疇の文字列操作のエッセンスとしては、ここで紹介したものがほとんど全てとなります。この長い記事を参考に理解する努力をしてみたのなら、やりたい文字列操作をどういう具合にやっていけばいいのかという基本というかコツみたいなものはつかめたと思います。つかめなかった人もヒントくらいにはなったのではないでしょうか?ここから先はプログラムされる人のそれぞれの文字列操作感覚に従って、プログラムを作りこんでいっていただければと思います。基本がわかっていれば、Webで検索してでてくるようなややこしい説明も理解していけるでしょう。やりたいことを実現するのは面倒で手数も多いと実感したと思います。効率よくやりたいことができるようになるまで、知恵を振り絞って、頑張ってみてください。ここまで理解しようとしたならきっとできるはずです。 | ||
+ | |||
+ | |||
+ | ここを参照してくれたみなさんが作れってくれたアプリが使いやすいものになって、いろんな人の人生を充実させるものになることを願います。 | ||
+ | |||
+ | |||
+ | [[C PlusPlus#Cにもあった技術|C++]]へ戻る | ||
+ | |||
+ | |||
<!-- | <!-- | ||
{|class="wikitable" | {|class="wikitable" |