文字コード(多言語化?)の取り扱いについて

このQ&Aのポイント
  • 多言語化や複数プラットフォームでの動作について考える必要が出てきた。
  • 文字コードの設定に関して、UNICODE文字セットを使うという選択肢がある。
  • コード内でのTCHARやLの扱いについて、基本的な表記法を誤っている可能性がある。
回答を見る
  • ベストアンサー

文字コード(多言語化?)の取り扱いについて

正直な話今まで多言語化とか複数プラットフォームでの動作といったことは あまり考えていなかったのですが(作った環境限定で動かしたりしてた) 今回その一歩としてまず文字コードの設定を気にしだしました そこでまず理解できないのが 現在 UNICODE文字セットを使う 設定でソースを作り TCHAR msg[100]; _stprintf_s(msg, L"Error (0x%x) (%d)\n", hr, __LINE__); といったようなコードを書きました 当然その環境ではコンパイルして動くのですが 文字コードセットを 設定なし にしてリビルドするとそのコードでは error C2665: 'sprintf_s' : 2 オーバーロードのどれも、すべての引数の型を変換できませんでした といったエラーが出ます TCHARやL としてコードを書いておくことで _UNICODEデファインの有無により 自動的にwhar_tやcharへの変換が行われると思っていたのですが 基本的な表記法を間違っているのでしょうか? それとも文字セットはそういったことではなくunicode文字セットにしたときは 多国語サポートを考慮して作っているので それで書いたソースを文字セット 設定なし でそのまま再構築できるという 考え方のほうが間違っているのでしょうか (そんなのかえたらソース変更が当たり前 ってことなんでしょうか?)     変えられる可能性があるのはマルチバイト文字セットのみ? 環境は VS2010(VC2010)です

質問者が選んだベストアンサー

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

L"ほげほげ" だと, UNICODE は完全に無視して wchar_t * になると思う. だから「文字コードセットを 設定なし にしてリビルドする」と第2引数が const char * を期待しているのに wchar_t * になってる からエラーになる... ということじゃないかな. で _T(), と.

koi1234
質問者

お礼

すいません 試行錯誤した上で _T より L のほうがいいのかと思い変更したのが悪さをしたようです (何かで _T でワーニング出て L で直った気がしますがそれも間違いかもしれません) 今回の件はご指摘のように_T に変更することでコンパイル通ることを確認したので 他の部分も同様に修正かけたいと思いますが別の問題が出てしまいました TCHAR msg[100]; BSTR buf = ::SysAllocString(msg); というコードがあり unicode ではコンパイルできますが 無指定だと error C2664: 'SysAllocString' : 1 番目の引数を 'TCHAR [100]' から 'const OLECHAR *' に変換できません。(新しい機能 ; ヘルプを参照) この場合は const OLECHAR * にキャストするしかないのでしょうか? その他にもいくつか方が合わなくなってしまう部分があるようなのですが そういった場合も最終的にはキャストなりで合わせこむしかないのでしょうか? よろしければお教え願います いずれにしても動作確認はする必要あるとは思ってます 回答ありがとうございました

koi1234
質問者

補足

時間空きましたが何パターンかコンパイルオプション変更しても リコンパイルで動くようにはなりました 未だ多国語 まではいきついていないのが実情ですが 時間を見て調べていきたいと思います

その他の回答 (3)

  • wormhole
  • ベストアンサー率28% (1619/5653)
回答No.4

>では今回に対して言えばどういった対処を取るべきだといわれるのでしょうか? #3の方がすでに書かれていますが、::SysAllocString()はOLECHARの文字列を要求してるのですからOLECHARの文字列に変換すればいいだけです。 これは::SysAllocString()の仕様を考えればおのずとわかる事だと思いますが。 >そこで固定文字列などを渡したい場合どういった方法とればいいのか >など疑問が満載状態になってしまいます 使用する関数やAPIの仕様から判断してください。 >ベースコードSDKのサンプルなどから持ってきてそういった状態なのですが >サンプルも文字セット気にしないで記載されているということなのでしょうか? 私にそのサンプルの事をたずねられても推測しかできませんが(私が書いたわけじゃないし)。 文字コード変換のサンプルでもない限り、そのサンプルが書かれた当時のそのプラットフォームで標準的に使われていた文字コードで書かれてるというだけじゃないですか。

koi1234
質問者

お礼

回答ありがとうございます ちょっと他の調べものでこちらの作業がなかなかできないのですが 変換マクロがあることはわかりましたのでもう少し時間とれたら ゆっくり確認したいと思うます 簡単にテストしたんですがまた何か勘違いしてるのか マクロ使ってもさらに別のエラーが発生して コンパイルができなくなっただけで解決はしていません 単純なキャストでは変換がきちんとされていないため まともに動かないことの確認はできました

回答No.3

TCHARとOLECHARの変換は http://msdn.microsoft.com/ja-jp/library/805c56f8(v=VS.90).aspx に以下の通り記載されています。つまりT2OLEとOLE2Tマクロを使用すればいいわけです。 以下 引用 OLE 変換マクロ -------------------------------------------------------------------------------- OLE 変換マクロは OLESTR 文字を扱うことを目的とした関数の処理用にデザインされています。OLE のヘッダーをチェックすると、LPCOLESTR と OLECHAR への参照が数多くあるのがわかります。これらの型は、OLE インターフェイスで使用する文字の型をプラットフォームに依存しない方法で参照するために使用されます。OLECHAR は Win16 のプラットフォームでは char に変換され、Win32 では WCHAR に変換されます。 MFC コード中の #ifdef ディレクティブの数を最小に抑えるために、OLE 文字列を扱う変換でも同じようなマクロが用意されています。頻繁に使用されるマクロは、次のとおりです。 T2COLE (LPCTSTR) -> (LPCOLESTR) T2OLE (LPCTSTR) -> (LPOLESTR) OLE2CT (LPCOLESTR) -> (LPCTSTR) OLE2T (LPCOLESTR) -> (LPCSTR)

koi1234
質問者

お礼

回答ありがとうございます ちょっと他の調べものでこちらの作業がなかなかできないのですが 変換マクロがあることはわかりましたのでもう少し時間とれたら ゆっくり確認したいと思うます 簡単にテストしたんですがまた何か勘違いしてるのか マクロ使ってもさらに別のエラーが発生して コンパイルができなくなっただけで解決はしていません

  • wormhole
  • ベストアンサー率28% (1619/5653)
回答No.2

>この場合は const OLECHAR * にキャストするしかないのでしょうか? 何でもかんでもキャストすればいいというものではありません。 TCHARの用に_UNICODEの有無により切り替わることがない型が使われているという事なのですから、ケースに応じた対処をするべきです。

koi1234
質問者

お礼

回答ありがとうございました >何でもかんでもキャストすればいいというものではありません。 それは言われる通りだと思いますが >ケースに応じた対処をするべきです。 では今回に対して言えばどういった対処を取るべきだといわれるのでしょうか? キャストしなくていい const OLECHAR * 型のデータを渡せということなのであれば そこで固定文字列などを渡したい場合どういった方法とればいいのか など疑問が満載状態になってしまいます   今回たまたま TCHAR 型の変数を渡してますが   渡したいデータとして標準関数からの戻り値(CStringデータ)だったり   固定の文字列だったり複数のパターンがあります        (いずれも unicode コンパイルでは問題でていません)   ベースコードSDKのサンプルなどから持ってきてそういった状態なのですが   サンプルも文字セット気にしないで記載されているということなのでしょうか? 文字コード変更でこれほど悩むとは思わなかったんで混乱してきてます 他に優先してやらないといけないことがあるので文字コード変更の対応(テスト) がなかなか進みません

関連するQ&A

  • 内部文字コードとは?

    javaは内部では文字をユニコードとして扱うとは、 どういう事でしょうか? 例えば、javaのブログラムをwindows上で作ったとして、 「こんにちわ」と出力させるプログラムを作ったとすると、 public class Hello{ public static void main(String[] args) { System.out.println("こんにちわ"); } } となりますよね、この時、このjavaのソースファイルを、 ユニコードとして保存して、コンパイル、実行しないと、 正常に動かないという事でしょうか? つまり、ソースをシフトJISで保存してJAVAでコンパイルをしようとすると、ソースコード中の文字をユニコードとして扱うため、 文字化けして、コンパイラは一体何の事か分からずエラーみたいな感じになるのでしょうか?(それとも自動で文字コードをユニコードに変換してくれるのかな?) 要するに、「内部文字コード」という言葉が何を指しているのかが分からないですが、よろしくお願いします。

  • 文字コードチェックについて

    題記の文字コードチェックについて教えていただきたいのですが、 入力情報に対して、S-JISのある範囲内の文字コードに該当していればエラーとするような文字コードチェックをしたいのですが、 どのようにすればよいでしょうか? 下記のコードも文字コードのチェックなのですが、これだとUnicodeでのチェックになってしまいます。 どうにかしてS-JISでチェックしたいのですがやり方がわかりません。。 よろしくお願い致します。 コード---------------------------------------- public class CodeCheck {  public static void main(String[] args) {   String str = "a";   char ch = str.charAt(0);   if(ch == 0x2460) {    // エラー処理   } else {    // 正常処理   }  } } ---------------------------------------------

    • ベストアンサー
    • Java
  • JAVAでSJISのコード変換

    JAVAで、UnicodeからSJISへのコード変換を行った上で ファイル出力を行いたいです。 たとえば文字列中にある「(1)」の文字コードが以下である時 ------------------------------- SJIS:8744 - UNICODE:2464 ------------------------------- 2464のコードを8744に変換した上でファイル出力したいです。 処理として、以下の様な形を考えているのですが 文字化けしてしまします。 ------------------------------- String source = "(1)あああああ"; 文字列の数分ループ処理↓ int code = (int) (source[x].charAt(i)); if (code == 2464) { strBuff.append(String.valueOf((char) (8744))); } ------------------------------- Unicodeで扱われているので「getByte("SJIS")」などとしているのですが 同様の結果となります。 何か良い手はないものでしょうか?

    • ベストアンサー
    • Java
  • 文字コード変換の場合わけ。

    あるURLのソースの文字コードを判定してUnicodeに変換する メソッドや方法はありませんか? URLによってshiftJISでかかれていたり、EUC-JP で書かれているページがあるのでそれを 判定してUnicodeに変換して出力する方法が欲しいのです。 現在は InputStreamReader isr = new InputStreamReader(is,"EUC-JP"); コンストラクタを用いてコード変換を行っています。 お願いします。

    • ベストアンサー
    • Java
  • 中国文字のプログラムでの取り扱い

    中国文字のVisual Basic6での取り扱いについて教えてください。 環境 Windows7、Visual Basic6、IE8 秀丸エディタなどでUTF-8モードとして、「书信」などの漢字(左の字が中国簡体字、右の信は日本文字と同じ)をファイルに入れておき、これを読み取って、HTML文で表示できるようにするプログラムを作ろうとしています。 Visual Basic6の変数に入れるとUnicodeとして処理されるので実行中に止めて表示させても、またHTML文書で表示させても”???”と文字化け状態になります。 そこでOKwebにてコード変換を教えていただいたのでUnicodeをUTF-8に変換すると「?信」となります。 何か変ですがこれをさらにUTF-8からUniCodeに変換すると”???”と表示されるようになります。 中国簡体字の部分だけがどうしても表示できません。どうしたら表示できるのでしょうか? なお本件とは直接の関係はありませんが、HTMLソースを秀丸で表示させて「书信」を張り付けると、ソースでも、またブラウザ・IE8で表示させても正しく「书信」と表示されます。

  • 文字コードANSIからUnicodeにしてください

    今日はじめたばかりの初心者です。 メモ帳でソースを作ってるのですが、 コードの文字数が多くなると、文字コードANSIからUnicodeにしてくださいとメモ帳から言われ、 Unicodeに変更して、保存すると、 http://localhost/tset.php でコードを確認すると、文字化けはしないのですが、おかしくなります。 だからって文字コードANSIにしていると、毎回Unicodeにしますか?と聞かれます。 こういう場合どうすればいいでしょうか? 他のテキストエディタハワードしか使ったことがないです。

    • ベストアンサー
    • PHP
  • 文字コード【utf-8】のHTMLを

    charset=utf-8で作成されているHTMLをDreamweaverで開くと テキストが文字化けしてしまいます。 他のテキストエディタで文字コードをUnicodeに設定して開いた場合も Web上で「ソースコードの表示」でソース表示してもやはり同じく文字化けしてしまいます。 この場合、どうしたら文字化けせずにソースを表示することができますか? できればDreamweaverで開けるとありがたいのですが・・・ アドバイスいただけると助かります。 どうぞ宜しくお願い致します。

    • ベストアンサー
    • HTML
  • VB6での文字コードダンプ

    VB6を使用して文字のダンプを取得したいのですが、UNICODE→SJIS変換しての バイト長を取得するものはよく見かけるのですが、全角文字の文字コードの取得法は、調べてはいるのですがなかなか見つかりません。 行いたいことは、全角の"あ"の場合、0x82、0xa0のように SJISでの1バイト毎の16進(10進でも可)の文字コードを 取得したいということです。 よろしくお願いします。

  • javaの文字コードについて

    いつもお世話になっております。 webで入れられた文字列に全角が含まれるか判定したいのですが、 文字コードについて質問させてください。 javaは標準では、String型は標準ではunicodeだと思うのですが、 これはutf-8なのでしょうか。utf-16なのでしょうか。 試しに以下のように"A"の文字をbyteに変換してみたところ、 String strTest = "A"; byte[] bbb = strTest.getBytes(); for(int i = 0 ; i < bbb.length ; i++){ System.out.println(bbb[i]); } "65"という結果が返ってきました。 http://ash.jp/code/unitbl1.htm 等文字コード表を見ると、"A"は"41"と定義されており、なぜ"65"が返ってくるのでしょうか。 変な質問ですいません。 関係無いと思いますが、ソースはS-JIS、windwos環境で実行しています。 よろしくお願いします。

    • ベストアンサー
    • Java
  • Mingwで扱うソースコードの文字コードについて

    Mingwでプログラムを作っているのですが、使用する文字コードについてご意見を伺いたくて質問いたします。 コレ!という解がないかもしれない質問なので、色々ご意見をいただければと思います。 よって、全く急ぎの質問ではありません。 1~2週間で解決できればいいな~というのんびりした質問です。 現在、Win7 32bit 環境で、C言語メインで開発しており、Mingwは2017年5月頃に入手したものをそのまま使っております。 バージョンは、 gcc version 6.3.0 (i686-posix-dwarf-rev2, Built by MinGW-W64 project) GNU gdb (GDB) 7.11.1 GNU ld (GNU Binutils) 2.27 iconv (GNU libiconv 1.9) GNU Make 3.81 等となっており、相当古いものです。現在のままでもさほど支障はないのですが、gccにいたっては既にナンバーが2遅れであり、そろそろバージョンアップしようと久しぶりにmingw-get-setup.exeを立ち上げました。 念のため旧バージョンのディレクトリ名を変えて上書きしないようにし、インストール完了しました。 そして、いつものようにmake経由でコンパイルコマンドを入力するとiconv関連でエラーが発生します。 cc1.exe: error: no iconv implementation, cannot convert from cp932 to UTF-8 make: *** [b-102.obj] Error 1 b-102.objというのがmainを含んだoファイルです(MakeファイルをborlandやVC++互換にしているため、拡張子がobjになっています) ソースコードの文字コードはSJIS、プログラム全体としては -DUNICODE -D_UNICODE オプションをつけて、文字列リテラルは _T("")マクロを使い、TCHAR型とtchar.hを使って、 UTF16を内部コードにしています。 コンパイルコマンドは gcc -finput-charset=cp932 -std=gnu99 -DUNICODE -D_UNICODE -O3 -Os -Wall -Wuninitialized -s -c -o b-102.obj b-102.c で、旧バージョンのmingwでは問題ないものでした。 ネットで調べてみると、Mingwの文字コード関係はときどきバグや設定ミスが入るとの事でしたので、2019年1月15日からバージョンアップするたびにインストールしてみていますが、2019年1月27日のバージョンに至るまで解決していません。 現在の最新バージョンとしているのは gcc version 8.2.0 (MinGW.org GCC-8.2.0-3) GNU gdb (GDB) 7.6.1 GNU ld (GNU Binutils) 2.31.1 iconv (GNU libiconv 1.14) GNU Make 3.81 であり、gdbのバージョンがなぜか古いこと以外は問題無いように思います。 そこで本題に戻るわけですが、いくつかの解決策からどれを選ぶか迷っています(私の知らない、想定していない解決策があるかもしれません)。 実際に色々やっている開発現場の方のご意見も頂戴したいと思います。 以下、当方で考えている解決策です。一長一短ありそうなので、「その方法は○○が面倒だ」「Mingwではその方法は△△の理由でオススメしない」など教えてください。 なお、現在環境を切り替えるため、コマンドプロンプトを起動する際に、旧バージョンと新バージョンで作業するため以下の環境変数をsetコマンドで一時設定して使っています。 この問題解決のため、新バージョンでは環境変数をいくつか追加設定していますがうまくいきません。 旧バージョン: PATH=C:\mingw32_2017\bin;%PATH% PATH=C:\mingw32_2017\msys\1.0\bin;%PATH% 新バージョン: set MINGW_HOME=C:\MinGW;%MINGW_HOME% set MSYS_HOME=C:\MinGW\msys\1.0;% MSYS_HOME% set C_INCLUDE_PATH=C:\MinGW\include;%C_INCLUDE_PATH% PATH=C:\MinGW\bin;%PATH% PATH=C:\MinGW\msys\1.0\bin;%PATH% 以下、当方の考えている解決策案です。当方にとって望ましい順です。 案1. 環境変数や設定ファイルを書き換えることで、iconvを望みどおりに動作させる。 現在はMINGW_HOME、MSYS_HOME、C_INCLUDE_PATHしか見つけておらず、もしかしたら新たに設定が追加されているかも?。 案2. コンパイルコマンドやリンカコマンドに適切なオプションを設定する? こういったことができるという情報は把握してないのですが、あるといいな、ぐらいです。 案3. ソースコードの文字コードを全てUTF16に置き換える。 かなり面倒ですが、一旦できれば今後は楽かもと思っています。UTF8にしたくないのは、どうせいつかはUTF16になっていくのに、中途半端に1バイト幅から?バイト幅まですごく可変長な文字コードを使いたくないという理由です。内部コードもUTF-16にしているので、ソースの文字コード、扱うファイルの文字コード、内部文字コードを揃えられたら楽です。 ただ、200近いソースコードを_T("")マクロでせっかくユニコード対応させたのに、口惜しくはあります。 また、MingwでUTF16は面倒すぎるという報告も多数見つけているので、不安ではあります。最新バージョンではどうなのでしょうか。 他にも、VC++やClangにも対応できる無難な文字コードを選びたいと思っています。 さらにいずれQtも使ってみたいので、そういった有名な外部ライブラリとの相性をご存知の方はご教授ください。 案4. makeでコンパイル命令を出す際に、自動的にiconvを呼び出して、別ファイルに出力するのではなく、フィルターのように機能させる方法があれば・・・。調べてみましたが、それらしい機能は見つかりませんでした。 案5. ソースコードをUTF8に統一する。 現在わかっている範囲で一番やりたくない方法です。 案6. Mingwのアップデートを待つ。 いまのところ効果無しですが、うまくいく目算があればもうすこし粘ろうと思います。 案7. 上記以外の方法。 当方が知らないだけで、インストール時の隠し設定とかあるかも、という期待を込めて。 現在うまくやってらっしゃる方、開発現場の裏技を知っている方、そのほか「面倒だけどウチはこれで妥協してる」など、いろいろな情報をお待ちしています。 よろしくお願いいたします。

専門家に質問してみよう