none
UNICODE CStringからShift-JIS char*への変換方法 RRS feed

  • 質問

  • 画面プログラムを作るのにVisualC++を使いはじめましたが、従来あるdllの引数が全部char*型なので、UNICODE CStringからShift-JIS char*への変換が必要となりました。

    JavaでのBufferedWriter(new OutputStreamWriter(文字列、えんこーど))のようなクラスないでしょうか?初歩的な質問ですが、教えてもらえると助かります。宜しく御願いします

    2007年6月6日 0:03

回答

  • UTF-8ならWideCharToMultiByteでも出来ますね。

    一応、(私が使っていた)CStringからバイト型配列へ変換するコードです。
    メモリ管理が面倒なので、afxtempl.hのCByteArrayを使っています。
    Sample
    BOOL XXXXX::ConvertUTF8(const CString src, CByteArray& dest) const
    {
        _bstr_t bSrc(src);
        dest.RemoveAll();
        const int len = 
    ::WideCharToMultiByte(CP_UTF8, 0, bSrc, -1, NULL, 0, NULL, NULL); if (len > 0) { dest.SetSize(len); if (::WideCharToMultiByte(CP_UTF8, 0, bSrc, -1,
    static_cast<LPSTR>(static_cast<void*>(dest.GetData())),
    len, NULL, NULL)) return TRUE; } return FALSE; }

    で、UTF-8のファイルを出力するときに使っています。
    Sample
    BOOL XXXXX::OutputFile()
    {
        TRY
        {
            CFile f(this->m_Target,
    CFile::modeCreate | CFile::modeWrite | CFile::shareDenyNone); CByteArray bin; // BOM f.Write("\xEF\xBB\xBF", 3); this->ConvertUTF8(
    _T("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\r\n"),
    bin); f.Write(bin.GetData(), bin.GetSize() - 1); f.Close(); } CATCH (CFileException, ex) { TCHAR err[524]; ex->GetErrorMessage(err, sizeof(err) / sizeof(err[0])); AfxMessageBox(err); return FALSE; } END_CATCH return TRUE; }
    2007年6月6日 2:01

すべての返信

  • 変換方法はいくつかあります。

    • APIの WideCharToMultiByte をつかう。
    • データ変換関数の wctomb(wctomb_s) をつかう。
    • ATLのマクロ W2A をつかう。
    • _bstr_tクラスをつかう。
    • その他のコンポーネント(ADODB.Streamとかmlangライブラリとか)をつかう。
    • CLRを使えるようにして、.NETのクラスのSystem.Text.Encodingあたりをつかう。


    のいずれかでしょう。
    (個人的に_bstr_tが簡単で使いやすいと思っています。)


    本格的なコード変換(5点目の使い方)については
    http://forums.microsoft.com/MSDN-JA/ShowPost.aspx?PostID=613442&SiteID=7
    を参考にしてください。


    ちなみにShift_JIS→CStringはコンストラクタがあるのでコード変換についてはCString
    がやってくれます。
    2007年6月6日 0:31
  • 蒼の洞窟さん、囚人さん返信ありがとうございました。返信があまりに早いのでビックリしました。

    UTF-8変換も必要だったので、Mlangクラスのサンプルコーディングもとても助かりました。

    2007年6月6日 1:40
  • UTF-8ならWideCharToMultiByteでも出来ますね。

    一応、(私が使っていた)CStringからバイト型配列へ変換するコードです。
    メモリ管理が面倒なので、afxtempl.hのCByteArrayを使っています。
    Sample
    BOOL XXXXX::ConvertUTF8(const CString src, CByteArray& dest) const
    {
        _bstr_t bSrc(src);
        dest.RemoveAll();
        const int len = 
    ::WideCharToMultiByte(CP_UTF8, 0, bSrc, -1, NULL, 0, NULL, NULL); if (len > 0) { dest.SetSize(len); if (::WideCharToMultiByte(CP_UTF8, 0, bSrc, -1,
    static_cast<LPSTR>(static_cast<void*>(dest.GetData())),
    len, NULL, NULL)) return TRUE; } return FALSE; }

    で、UTF-8のファイルを出力するときに使っています。
    Sample
    BOOL XXXXX::OutputFile()
    {
        TRY
        {
            CFile f(this->m_Target,
    CFile::modeCreate | CFile::modeWrite | CFile::shareDenyNone); CByteArray bin; // BOM f.Write("\xEF\xBB\xBF", 3); this->ConvertUTF8(
    _T("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\r\n"),
    bin); f.Write(bin.GetData(), bin.GetSize() - 1); f.Close(); } CATCH (CFileException, ex) { TCHAR err[524]; ex->GetErrorMessage(err, sizeof(err) / sizeof(err[0])); AfxMessageBox(err); return FALSE; } END_CATCH return TRUE; }
    2007年6月6日 2:01