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 /> | ||
== '''日本語文字列''' == | == '''日本語文字列''' == | ||
+ | |||
char型の配列で1byte、1文字を表現できるascii文字コードというものを使っていましたが、問題点はいくつかありますが、そのままでも日本語全角文字は表現できます。日本語文字コードは2Byteで表現されます。 | char型の配列で1byte、1文字を表現できるascii文字コードというものを使っていましたが、問題点はいくつかありますが、そのままでも日本語全角文字は表現できます。日本語文字コードは2Byteで表現されます。 | ||
全角のアルファベットからカタカナ、ひらがな、漢字、記号、あまり使わない漢字を含めて65536種類を00 00からFF FFまでで、表現しています。最初の1byteが0x80~0x9F、0xE0~0xFCならばasciiコードでは定義していないため、その後ろの1byteも読み込んで1文字だと処理してくれます。マルチバイト文字と呼んでいます。asciiコードですでに使われている部分は使えないとしても、日本語文字コードは15616種類を使えます。これでも十分です。<br /> | 全角のアルファベットからカタカナ、ひらがな、漢字、記号、あまり使わない漢字を含めて65536種類を00 00からFF FFまでで、表現しています。最初の1byteが0x80~0x9F、0xE0~0xFCならばasciiコードでは定義していないため、その後ろの1byteも読み込んで1文字だと処理してくれます。マルチバイト文字と呼んでいます。asciiコードですでに使われている部分は使えないとしても、日本語文字コードは15616種類を使えます。これでも十分です。<br /> | ||
39行: | 43行: | ||
− | VisualSutdioのプロジェクトの設定でもUnicode文字列とマルチバイト文字列、どっちも使わないってのが設定できます。VisualStudioをアクティブにしている状態で[Alt]+[F7]でプロジェクトのプロパティが表示されるダイアログが表示されます。左側のツリー構造から構成プロパティの中の全般を選択すると右側のビュー表示されるリストに文字セットというのがあります。リストには「Unicode文字セットを使用する/マルチバイト文字セットを使用する/設定なし」の3つがあり、ここで選択した設定にしたがって、Visual C++だけの機能になりますが、TCHAR型という文字列変数を定義することで、設定にしたがって、マルチバイトおよびUnicodeを判別してコンパイルしてくれます。因みにワイド文字列型では、wchar_t型というのを使うのですが、TCHAR型は、Unicode設定だとwchar_tに置き換わることになります。 | + | VisualSutdioのプロジェクトの設定でもUnicode文字列とマルチバイト文字列、どっちも使わないってのが設定できます。VisualStudioをアクティブにしている状態で[Alt]+[F7]でプロジェクトのプロパティが表示されるダイアログが表示されます。左側のツリー構造から構成プロパティの中の全般を選択すると右側のビュー表示されるリストに文字セットというのがあります。リストには「Unicode文字セットを使用する/マルチバイト文字セットを使用する/設定なし」の3つがあり、ここで選択した設定にしたがって、Visual C++だけの機能になりますが、TCHAR型という文字列変数を定義することで、設定にしたがって、マルチバイトおよびUnicodeを判別してコンパイルしてくれます。因みにワイド文字列型では、wchar_t型というのを使うのですが、TCHAR型は、Unicode設定だとwchar_tに置き換わることになります。 |
− | ワイド文字列では、文字列リテラルへは L | + | どっちも使わない、設定なしを選択した方がよい場合もあります。それはワイド文字、Unicodeとか、マルチバイト文字を使わないアプリ構成にしたい場合です。Windows.hで提供されるようなAPIでさえも文字列を引数にとることはありますが、この引数の受け取り方が設定なしの場合、なにかとchar型のままでいいよ。という具合になります。そうするとwchar型とかtchar型を使わなくてもよいので、ひたすら文字列はchar型のみを扱えばよいことになります。最初のうちは英語のみ対応のアプリにして練習するのもありかなと思いますので、設定なしという道もあっていいかと思います。むしろ学術的なことに専念するアプリやそういった専門書なんかでは、設定なしを使って説明されるパターンがあります。これは文字列うんぬんを語ると限られたページの中で専門的なことが説明できなくなるからだと思います。ここで書いたことを知っていればあとで、ワイド文字対応に応用することなんかは簡単なことですから、別の専門的なことを勉強するにあたっては、設定なしを選択して、英語版アプリ(1バイト文字、ASCIIコード範囲)を作る覚悟で取り組むということもあっていいかと思います。 |
+ | |||
+ | |||
+ | ワイド文字列では、文字列リテラルへは L"yonewiki" としなければならないし、例えば文字列を引数にする関数もwprintf(L"cStr=%s",cStr );とかに多数の書き換えが必要になります。そして、ワイド文字がどこの国の言葉を扱うのかを定義するには、setlocale関数で設定が必要で、setlocale( LC_ALL, "Japanese" );※リテラルの設定では省略されていますが、setlocale( LC_ALL, "Japanese_Japan.932" ); /> | ||
と設定していることになります。出力するときには日本語のShift_JISにしてねということです。今はWindowsPCのコマンドプロンプトで動作を確認しているからです。<br /> | と設定していることになります。出力するときには日本語のShift_JISにしてねということです。今はWindowsPCのコマンドプロンプトで動作を確認しているからです。<br /> | ||
52行: | 59行: | ||
http://msdn.microsoft.com/ja-jp/library/x99tb11d(v=vs.90).aspx<br /> | http://msdn.microsoft.com/ja-jp/library/x99tb11d(v=vs.90).aspx<br /> | ||
<br /> | <br /> | ||
− | のようにsetlocale関数の記述が必要になります。setlocale関数を使うには#include<locale.h> | + | のようにsetlocale関数の記述が必要になります。setlocale関数を使うには#include<locale.h>が必要です。setlocale関数でも引数に文字列リテラルを与えるので、そこでワイド文字列を使うために_wsetlocale関数もあります。<br /> |
− | + | ||
− | _wsetlocale( LC_ALL, L | + | |
− | とします。こちらはwchar.hをインクルードするだけで使えるとのこと。 | + | _wsetlocale( LC_ALL, L"Japanese" );<br /> |
+ | |||
+ | |||
+ | とします。こちらはwchar.hをインクルードするだけで使えるとのこと。 | ||
wcslenは文字列の文字数をカウントする関数です。通常のマルチバイト文字でもワイド文字でもない、何もしない関数はstrlen関数になります。<br /> | wcslenは文字列の文字数をカウントする関数です。通常のマルチバイト文字でもワイド文字でもない、何もしない関数はstrlen関数になります。<br /> | ||
− | + | ||
− | + | ||
− | さらにwcher_t型を使うには、プリプロセッサでwchar.hを読み込まなくてはならず、 | + | |
+ | さらにwcher_t型を使うには、プリプロセッサでwchar.hを読み込まなくてはならず、 | ||
+ | |||
+ | |||
<nowiki>#include<wchar.h></nowiki>と記述しないといけないです。<br /> | <nowiki>#include<wchar.h></nowiki>と記述しないといけないです。<br /> | ||
従って、ワイド文字列版のプログラムは以下のようになります。 | 従って、ワイド文字列版のプログラムは以下のようになります。 | ||
− | < | + | |
+ | |||
+ | <syntaxhighlight2 lang="cpp" line start="1"> | ||
#include <iostream> | #include <iostream> | ||
//#include<locale.h> wchar.hがインクルードされていれば、いらない。 | //#include<locale.h> wchar.hがインクルードされていれば、いらない。 | ||
#include<wchar.h> | #include<wchar.h> | ||
int main() { | int main() { | ||
− | _wsetlocale( LC_ALL, L | + | _wsetlocale( LC_ALL, L"Japanese"); |
− | wchar_t cStr[]=L | + | wchar_t cStr[]=L"よねウィキyonewiki"; |
− | wprintf(L | + | wprintf(L"cStr0=%s sizeof=%d StrCount=%d", cStr0,sizeof(cStr0),wcslen(cStr0)); |
} | } | ||
− | </ | + | </syntaxhighlight2> |
<br /> | <br /> | ||
− | + | TCHAR型も同じようなものですが、プロジェクトの設定次第で置き換わるということが特徴です。これでプロジェクトの設定をUnicodeの文字セットにしていれば、wchar_t型になり、さらにTCHAR型を使うには、プリプロセッサでtchar.hを読み込まなくてはならず、<br /> | |
− | + | ||
− | + | <nowiki>#include<tchar.h></nowiki> | |
− | <nowiki>#include<tchar.h></nowiki | + | |
− | + | と記述しないといけないです。setlocale関数も_tsetlocale関数として置き換えておくことができます。Unicodeセットのプロジェクト設定なら結局_wsetlocaleに置き換わるだけです。文字列リテラルは_T(" ")といった形式で記述しておきます。_tcslen関数はwcslen関数と同じです。このようにマルチバイト文字列版、ワイド文字列版、プロジェクト設定に従うTCHAR版の3つの関数があります。cout関数にはTCHAR版が無いようなので、最初からstd::wcoutと記述するか、wcout関数と_tcout関数が同じになるように定義する必要があります。実用的にはあまり使わない関数なので、あってもなくても困りません。<br /> | |
− | + | ||
− | + | ||
− | + | C++標準関数の文字列操作系の関数を使わないようにするのが、自分は良いと思います。自分のパソコンの環境だけで、ちょっとしたことのために、マクロ定義するような手法は嫌いです。何をやってるのかが分からなくなっていきやすいような気がします。長い置き換えが必要な部分だけをプログラムにするようにしています。<br /> | |
− | + | ||
− | + | ||
− | + | ||
− | C++ | + | |
− | + | ||
− | + | ||
<br /> | <br /> | ||
従って、TCHAR版のプログラムは以下のようになります。<br /> | 従って、TCHAR版のプログラムは以下のようになります。<br /> | ||
− | < | + | <syntaxhighlight2 lang="cpp" line start="1"> |
#include <iostream> | #include <iostream> | ||
//#include<locale.h> tchar.hがインクルードされていれば、いらない。 | //#include<locale.h> tchar.hがインクルードされていれば、いらない。 | ||
98行: | 107行: | ||
_tprintf(_T("cStr0=%s sizeof=%d StrCount=%d"), cStr0,sizeof(cStr0),_tcslen(cStr0)); | _tprintf(_T("cStr0=%s sizeof=%d StrCount=%d"), cStr0,sizeof(cStr0),_tcslen(cStr0)); | ||
} | } | ||
− | </ | + | </syntaxhighlight2> |
出力結果は | 出力結果は | ||
− | < | + | <syntaxhighlight2 lang="cpp" line start="1"> |
cStr0=表示:よねウィキの機能<yonewiki> sizeof=44 StrCount=21 | cStr0=表示:よねウィキの機能<yonewiki> sizeof=44 StrCount=21 | ||
− | </ | + | </syntaxhighlight2> |
となります。 | となります。 | ||
− | TCHAR型のユニコード(UTF-16) | + | TCHAR型のユニコード(UTF-16)設定にした場合、wchar_t型のcStr0は配列番号0~21の22の大きさを持つ配列になります。Unicode文字セットですのでShft_JISとは異なる数値が使われますが、0番から順に<br /> |
− | + | ||
0x8868(表),0x793A(示),0xFF1A(:),0x3088(よ),0x306D(ね),0x30A6(ウ),0x30A3(ィ),0x30AD(キ),0x306E(の),0x6A5F(機),0x80FD(能)<br /> | 0x8868(表),0x793A(示),0xFF1A(:),0x3088(よ),0x306D(ね),0x30A6(ウ),0x30A3(ィ),0x30AD(キ),0x306E(の),0x6A5F(機),0x80FD(能)<br /> | ||
0x003C(<nowiki><</nowiki>),0x0079(y),0x006F(o),0x006E(n),0x0065(e),0x0077(w),0x0069(i),0x006B(k),0x0069(i),0x003E(<nowiki>></nowiki>),0x0000(\0)<br /> | 0x003C(<nowiki><</nowiki>),0x0079(y),0x006F(o),0x006E(n),0x0065(e),0x0077(w),0x0069(i),0x006B(k),0x0069(i),0x003E(<nowiki>></nowiki>),0x0000(\0)<br /> | ||
− | + | ||
− | + | のように格納されています。あんまり変わり映えしませんが、プロジェクトの設定に従うという意味ではTCHAR型を使うのが少しお勧めです。気を付けなければならないのは、Shift_JIS(CP932)コード文字セットで格納された配列をユニコード文字セットのプロジェクトで受け取ったり、その逆のことが起こったりする場合には変換が必要になったりと、いいことばかりではありません。この他、文字コードにはShift_JIS(CP932)ではないShift_JISやEUCやMac日本語といった文字コードもあり、可能性だけで考えると | |
− | + | ||
− | + | ||
− | + | ||
Unicode:UTF-8/UTF-16/UTF-32<br /> | Unicode:UTF-8/UTF-16/UTF-32<br /> | ||
Shift_JIS:CP932/shift_jis/shift_jis2000/shift_jis2004<br /> | Shift_JIS:CP932/shift_jis/shift_jis2000/shift_jis2004<br /> | ||
119行: | 127行: | ||
JIS:CP50220/ISO-2022-JP/ISO-2022-JP-1/ISO-2022-JP-2004/ISO-2022-JP-3<br /> | JIS:CP50220/ISO-2022-JP/ISO-2022-JP-1/ISO-2022-JP-2004/ISO-2022-JP-3<br /> | ||
JIS 1Byte:ISO-2022-JP/CP50221<br /> | JIS 1Byte:ISO-2022-JP/CP50221<br /> | ||
− | + | ||
− | + | ||
− | + | といった文字コードが存在し、外国語文字コードセットも含めるとかなりの数の文字コードが世界に広がっています。Unicodeも扱いがいくつかあるため、実はもう少し勉強しないといけないです。VisualStudioでUnicodeと選択した場合は、UTF-16で扱われているということになります。UTF-8では英数字が1Byte、日本語は3Byteを使います。テキストエディタは、このあたりの解釈が厳密で、ファイルを保存するときにも文字コードセットと符号化方式を遵守していますし、互換性を高めているものが、多いです。複雑過ぎて、自分には作れそうもないですね。<br /> | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
WindowsのVisualStudioなどでWin32 APIを使える環境であれば、以下のような型もあります。<br /> | WindowsのVisualStudioなどでWin32 APIを使える環境であれば、以下のような型もあります。<br /> | ||
LPCSTR =const CHAR * <br /> | LPCSTR =const CHAR * <br /> | ||
142行: | 149行: | ||
であり、その略の型名が対応しているとのこと。<br /> | であり、その略の型名が対応しているとのこと。<br /> | ||
PCSTR/PCWSTR/PCTSTR/PSTR/PWSTR/PTSTRと先頭にLが着かないものはWin16時代に使われたものですが、今では差がありません。<br /> | PCSTR/PCWSTR/PCTSTR/PSTR/PWSTR/PTSTRと先頭にLが着かないものはWin16時代に使われたものですが、今では差がありません。<br /> | ||
− | + | ||
− | MFC(MicrosoftFaundationClass) | + | |
− | + | MFC(MicrosoftFaundationClass)というMicrosoftが提供しているクラスの文字列型には文字列の操作を強化したCStringもあります。有名なので手ごわいですが、これはMFCです。MFCは無料では配られていないクラスライブラリでして、Microsoftが定義した型ってのはすごく一般的にも使われるくらい流行します。ということで、使うべき型は、WIN32 APIでもLPCTSTR/PCTSTRあるいはLPTSTR/PTSTRということになりましょうか。とはいっても、世界中にはいろんな型の文字列で操作されますので、いろいろな変換が必要になります。<br /> | |
− | + | ||
− | + | ||
− | + | ここではwchar_t型で文字列を使うために、TCHAR型を使い、ワイド文字列用の各関数wcsで始まるような関数を使います。マルチバイト文字列とした場合はchar型でマルチバイト文字列用の各関数_wbやwbで始まるような関数に置き換えられることを意味します。ってことはstrcpyという文字列コピー関数や、strcat(文字列連結)、strlen(文字列カウント)のようなstrで始まるようなC標準ライブラリ関数は使われないことになります | |
− | + | ||
− | + | ||
− | + | 最近は文字列操作関数にxxx_sやxxx_lのようなセキュア思想(本当に安全なのかどうかは不明?使い方よっては間違いだらけのプログラムになる可能性もある)の文字列操作関数がありまして、大雑把に分類すると文字列操作の関数は上記のようなことから、以下のような文字列操作関数に分類できます。<br /> | |
− | + | ||
− | + | ||
− | + | ||
− | 最近は文字列操作関数にxxx_sやxxx_lのようなセキュア思想(本当に安全なのかどうかは不明?使い方よっては間違いだらけのプログラムになる可能性もある) | + | |
− | + | ||
*strxxx系関数<br /> | *strxxx系関数<br /> | ||
*マルチバイト文字_mbxxxx関数/mbxxxx関数<br /> | *マルチバイト文字_mbxxxx関数/mbxxxx関数<br /> | ||
173行: | 175行: | ||
LPCSTR/LPCWSTR/LPCTSTR/LPSTR/LPWSTR/LPTSTR/PCSTR/PCWSTR/PCTSTR/PSTR/PWSTR/PTSTR/<br /> | LPCSTR/LPCWSTR/LPCTSTR/LPSTR/LPWSTR/LPTSTR/PCSTR/PCWSTR/PCTSTR/PSTR/PWSTR/PTSTR/<br /> | ||
という型…<br /> | という型…<br /> | ||
− | + | ||
− | + | ||
− | + | どれか一つに決めて使うのは自分次第ですが、世界中のプログラマがどれを使うかは、わかりません。しかもどの関数も微妙に動作が違ったりするので、完全な理解をしようとすると、途方に暮れそうになります。でも、まぁそれだけの種類があるんだなぁとわかってさえいれば、その都度、変換方法を調べるということができるので、それでいいのかなぁと思ったりもします。で、文字コードセット変換…リトルエンディアン…ビッグエンディアン…文字コードセットの符号化方式UTF-8/UTF-16/UTF-32その他…もうね。なんか崩壊してるような気もするけど、やるしかないわなorz<br /> | |
− | + | ||
− | + | ||
− | + | 学校で教えてくれるプログラミングがいかにその一部分だけを勉強していたのかを思い知らされる現実。そして、これを覚えたところでWindowsプログラミングができるわけでもないという、目指すべき頂上の遠さ。全部を理解しようなんて思わないことですね。必要最低限の装備でどこまで登れるか?登山はあんまりやったことがないのでアレなんすけど<br /> | |
− | + | ||
− | + | ||
− | + | そんな軽装備で山登りなんて始めたら、間違いなく死ににいくようなもんです。それでも目指すべきところがあるのならば、頑張るしかないっすね。自分自身はMFCを使ったアプリも複雑過ぎて理解しきれなかったし、ある程度は理解しようとしたんですけど…。C++を理解して、MFCのちょいかじり、さらにその先にあるC++/CLI、DirectShowを使ってみたりもしましたが、いやはや。どこまで理解できたのやら(汗。Win32APIだけでUSBラジオを操作したり、音を出力する質素なアプリとか、そういうのを作るのが精一杯でしたね。あと面白いのはSteinBerg社の提供しているVSTiスケルトンから音楽やMIDI処理系のDLL開発をするのも楽しかったような。 | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
自分もわからなかったことを、もう一度、理解してみようと思います。<br /> | 自分もわからなかったことを、もう一度、理解してみようと思います。<br /> | ||
== '''マルチバイト文字列、ワイド文字列の相互変換''' == | == '''マルチバイト文字列、ワイド文字列の相互変換''' == | ||
まずは、文字列の配列で以下のように格納されているものがあって、<br /> | まずは、文字列の配列で以下のように格納されているものがあって、<br /> | ||
+ | |||
TCHAR *cStr0[]={_T("表示:よねウィキの機能<yonewiki>"),_T("表示:よねウィキの機能1<yonewiki>"),_T("表示:よねウィキの機能2<yonewiki>")};<br /> | TCHAR *cStr0[]={_T("表示:よねウィキの機能<yonewiki>"),_T("表示:よねウィキの機能1<yonewiki>"),_T("表示:よねウィキの機能2<yonewiki>")};<br /> | ||
− | + | ||
− | + | ||
− | < | + | を単純にpcStr0というポインタ変数を使って、まるまるコピーする場合はこんな風に自分ならやります。動的にメモリを確保してもらいますが、それで効率が本当にいいのか悪いのかは知りません。なんとなくやりきった感じだけはします。<br /> |
+ | <syntaxhighlight2 lang="cpp" line start="1"> | ||
#include <iostream> | #include <iostream> | ||
//#include<locale.h> tchar.hがインクルードされていれば、いらない。 | //#include<locale.h> tchar.hがインクルードされていれば、いらない。 | ||
219行: | 217行: | ||
return 0; | return 0; | ||
} | } | ||
− | </ | + | </syntaxhighlight2> |
− | + | 本当は12行目のコピーをする関数である_tcscpy_s関数は語尾の_sの無い関数を使いたいところですが、warningが表示されるので、あえて使いこなします。_tcscpy_sの第一引数はコピー先のTCHAR型先頭アドレスでコピーするのに必要な配列の大きさを持っていれば良いです。第二引数では、コピー先の配列の大きさを指定しています。第三引数はコピー元のTCHAR型の先頭アドレスです。<br /> | |
− | + | ||
− | + | ||
− | + | ||
− | + | 7行目のNew演算子では、TCHAR型のポインタのポインタ型の配列大きさを3を確保して、実体化しています。アドレスを保持できる4Byteの大きさの領域が配列番号0~3まで作られたことになります。10行目のNew演算子では、cStr[0]~[2]の文字列の文字数+1の大きさの配列をTCHAR型で確保します。ワイド文字列のwchar_t型でも21文字+1、22文字+1、22文字+1と順番に確保しますし、マルチバイト文字ならchar型ですので、すべて全角文字に対しては2byte、2文字分の領域が必要だと計算し、32文字+1、33文字+1、33文字+1を確保します。何故+1文字分を確保するかと言えば、文字列の最後には\0を格納してくれるので、その分をあけておかなければなりません。<br /> | |
− | + | ||
− | + | ||
− | + | 18行目、20行目では、delete演算子で動的生成した領域の放棄を宣言して、リソースを返却します。使い終わったら速やかに、返す。<br /> | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
出力結果はマルチバイト文字設定だと<br /> | 出力結果はマルチバイト文字設定だと<br /> | ||
− | < | + | <syntaxhighlight2 lang="cpp"> |
cStr0=表示:よねウィキの機能<yonewiki> sizeof=3 StrCount=32 | cStr0=表示:よねウィキの機能<yonewiki> sizeof=3 StrCount=32 | ||
cStr0=表示:よねウィキの機能<yonewiki> | cStr0=表示:よねウィキの機能<yonewiki> | ||
255行: | 248行: | ||
pcStr0=表示:よねウィキの機能2<yonewiki> | pcStr0=表示:よねウィキの機能2<yonewiki> | ||
cStr0=表示:よねウィキの機能2<yonewiki> | cStr0=表示:よねウィキの機能2<yonewiki> | ||
− | </ | + | </syntaxhighlight2> |
となります。<br /> | となります。<br /> | ||
ワイド文字列設定なら<br /> | ワイド文字列設定なら<br /> | ||
− | < | + | <syntaxhighlight2 lang="cpp"> |
cStr0=表示:よねウィキの機能<yonewiki> sizeof=3 StrCount=21 | cStr0=表示:よねウィキの機能<yonewiki> sizeof=3 StrCount=21 | ||
sizecStr0=0,cStr0=表示:よねウィキの機能<yonewiki> | sizecStr0=0,cStr0=表示:よねウィキの機能<yonewiki> | ||
279行: | 272行: | ||
pcStr0=表示:よねウィキの機能2<yonewiki> | pcStr0=表示:よねウィキの機能2<yonewiki> | ||
cStr0=表示:よねウィキの機能2<yonewiki> | cStr0=表示:よねウィキの機能2<yonewiki> | ||
− | </ | + | </syntaxhighlight2> |
− | となります。Visual C++ | + | となります。Visual C++をつかわれているのであれば、プロジェクトの設定をマルチバイトにしたり、Unicodeにしてみたりして下さい。TCHAR型で記述しているので、どちらでも動作すると思います。<br /> |
− | + | ||
− | + | ||
− | + | それで、なんでしたっけ、ワイド文字列とマルチバイト文字列の相互互換なんですけど、ようするにこのコピーをするときにワイド文字列とマルチバイトが混じっているケースで考えて、どのように対処すればいいのかで、 | |
− | + | 説明ができると思ったのでした。mbstowcs関数とwcstombs関数でやりとりが出来るようになっています。実際、こんなケースがあるのかは知りませんが、こんな関数があるってことは、テキストをどこからか読み込んだ場合とか、そういったプログラムから引数として受け取るとか、そういったケースもあるのでしょう。関数の引数はそれぞれ異なるので、気を付けなければなりません。<br /> | |
− | + | ||
− | + | ||
− | + | で、無理矢理にそういったサンプルのプログラムを作るのは意外と面倒でして、サンプルは鋭意執筆中ということにしておきたいと思います。ぉぃ。っていうか、MSDNライブラリが落っこちてるみたいで、厳密な解釈を調べながら書くことができない。mbstowcs関数にも_tbstowcsとかmbstowcs_sとかmbstowcs_s_lとかあると思うんですけど、その辺りを知ることが出来ない。その逆もしかり。<br /> | |
− | + | ||
− | + | ||
− | <br /> | + | ようはchar型に収められた文字列をwchar_t型に変換したり、wchar_t型で収められた文字列をchar型に変換したりするってことなんですけど。UnicodeとShift_JISの変換もここで知っておくべきか…。つうか、この記事、長すぎっ。誰も理解できないんじゃね?って思う今日この頃。<br /> |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
とかいいつつ、サンプルプログラムを作りました。<br /> | とかいいつつ、サンプルプログラムを作りました。<br /> | ||
mbstowcs関数とwcstombs関数はやはり、mbstowcs_s関数とwcstombs_s関数があって更には、<br /> | mbstowcs関数とwcstombs関数はやはり、mbstowcs_s関数とwcstombs_s関数があって更には、<br /> | ||
307行: | 294行: | ||
http://msdn.microsoft.com/ja-jp/library/vstudio/s7wzt4be(v=vs.110).aspx<br /> | http://msdn.microsoft.com/ja-jp/library/vstudio/s7wzt4be(v=vs.110).aspx<br /> | ||
サンプルプログラムは以下のとおりです。<br /> | サンプルプログラムは以下のとおりです。<br /> | ||
− | < | + | <syntaxhighlight2 lang="cpp" line start="1"> |
#include <iostream> | #include <iostream> | ||
//#include<locale.h> tchar.hがインクルードされていれば、いらない。 | //#include<locale.h> tchar.hがインクルードされていれば、いらない。 | ||
381行: | 368行: | ||
return 0; | return 0; | ||
} | } | ||
− | </ | + | </syntaxhighlight2> |
前半部分にマルチバイト文字→ワイド文字変換<br /> | 前半部分にマルチバイト文字→ワイド文字変換<br /> | ||
後半部分にワイド文字→マルチバイト文字変換<br /> | 後半部分にワイド文字→マルチバイト文字変換<br /> | ||
の処理を記述しました。<br /> | の処理を記述しました。<br /> | ||
mbstowcs_s(sizeReturnValue, NULL, 0,cStr1[i], 0);<br /> | mbstowcs_s(sizeReturnValue, NULL, 0,cStr1[i], 0);<br /> | ||
− | + | のように第二引数には本来、変換後の文字列の先頭アドレスを記述しますが、NULLと指定して、第三引数の変換後の配列要素数も0にして、第四引数に変換元の文字列の先頭アドレスを記述し、変換する要素数も0を指定するとsize_t型のポインタ変数sizeReturnValueに変換に必要な配列サイズが返ってきます。その返却された値を | |
− | + | ||
− | + | ||
− | + | requiredSize = *sizeReturnValue;のようにしてコピーしておいて、 | |
− | requiredSize = *sizeReturnValue;のようにしてコピーしておいて、 | + | |
+ | |||
mbstowcs_s(sizeReturnValue, pcStr2[i], requiredSize, cStr1[i], requiredSize);<br /> | mbstowcs_s(sizeReturnValue, pcStr2[i], requiredSize, cStr1[i], requiredSize);<br /> | ||
+ | |||
+ | |||
とすることで変換がされます。<br /> | とすることで変換がされます。<br /> | ||
逆のwcstombs_sも同様です。やったことないようなプログラムでしたので、たまには、こうして確かめてみるのも良いですね。<br /> | 逆のwcstombs_sも同様です。やったことないようなプログラムでしたので、たまには、こうして確かめてみるのも良いですね。<br /> | ||
<br /> | <br /> | ||
− | + | ちょっと出力結果に冗長さを設定したサンプルプログラムなので、以下のように出力が長くなりましたが、全部貼っておきます。<br /> | |
− | + | <syntaxhighlight2 lang="cpp"> | |
− | + | ||
マルチバイト文字→ワイド文字変換 | マルチバイト文字→ワイド文字変換 | ||
620行: | 609行: | ||
pcStr0=表示:よねウィキの機能2<yonewiki> | pcStr0=表示:よねウィキの機能2<yonewiki> | ||
cStr1=表示:よねウィキの機能2<yonewiki> | cStr1=表示:よねウィキの機能2<yonewiki> | ||
− | </ | + | </syntaxhighlight2> |
ってな感じになります。マルチバイト文字に変換することでShift_JIS cp932になっていることもわかったかと思います。<br /> | ってな感じになります。マルチバイト文字に変換することでShift_JIS cp932になっていることもわかったかと思います。<br /> | ||
人に見せるのに、出力部分の適当さ加減はすごいね。でも、これって内部的な努力は凄いけど、外部から見れば何も変化を感じないので、<br /> | 人に見せるのに、出力部分の適当さ加減はすごいね。でも、これって内部的な努力は凄いけど、外部から見れば何も変化を感じないので、<br /> | ||
さみしいね。次は文字列の操作の記事でも書きます。<br /> | さみしいね。次は文字列の操作の記事でも書きます。<br /> | ||
<br /> | <br /> | ||
− | [[C PlusPlus|C++]]へ戻る | + | |
+ | |||
+ | [[C PlusPlus#Cにもあった技術|C++]]へ戻る |