サンプル集  >  VC  >  iniファイルの書き込み
wchar_t型とchar型の相互変換A
2012/11/15

以前、同じ事をwchar_t型とchar型の相互変換で行った時、エラーを力技で解決しましたが気になったので再度調査しました。

◆環境
OS Windows XP Professional Version 2002 Service Pack 3
VC Microsoft Visual C++ 2008 91179-136-7480673-60595

以前はmbstowcs_s関数でエラーが出ていました。 よくよく調べると、mbstowcs_s関数の第三パラメータは「文字数」を指定しなければなりませんでした。 wchar_t型の配列[13+1]をsizeofでサイズを見ると28になりました。 領域自体が14文字分しかないので、28を指定したことにより動作がおかしくなったようです。

wchartToChar.cpp
  1: 
  2: 
  3: 
  4: 
  5: 
  6: 
  7: 
  8: 
  9: 
 10: 
 11: 
 12: 
 13: 
 14: 
 15: 
 16: 
 17: 
 18: 
 19: 
 20: 
 21: 
 22: 
 23: 
 24: 
 25: 
 26: 
 27: 
 28: 
 29: 
 30: 
 31: 
 32: 
 33: 
 34: 
 35: 
 36: 
 37: 
 38: 
 39: 
 40: 
 41: 
 42: 
 43: 
 44: 
 45: 
 46: 
 47: 
 48: 
 49: 
 50: 
 51: 
 52: 
 53: 
 54: 
 55: 
 56: 
 57: 
 58: 
 59: 
 60: 
 61: 
 62: 
 63: 
 64: 
 65: 
 66: 
 67: 
 68: 
 69: 
 70: 
 71: 
 72: 
 73: 
 74: 
 75: 
 76: 
 77: 
 78: 
 79: 
 80: 
 81: 
 82: 
 83: 
 84: 
 85: 
 86: 
 87: 
 88: 
 89: 
 90: 
 91: 
 92: 
 93: 
 94: 
 95: 
 96: 
 97: 
 98: 
 99: 
100: 
101: 
102: 
103: 
104: 
105: 
106: 
107: 
108: 
109: 
110: 
111: 
112: 
113: 
114: 
115: 
116: 
117: 
118: 
119: 
120: 
121: 
122: 
123: 
124: 
125: 
126: 
127: 
128: 
129: 
130: 
131: 
132: 
133: 
134: 
135: 
136: 
137: 
138: 
139: 
140: 
141: 
142: 
143: 
144: 
145: 
146: 
147: 
148: 
149: 
150: 
151: 
152: 
153: 
154: 
155: 
156: 
157: 
158: 
159: 
// wchartToChar.cpp : コンソール アプリケーションのエントリ
// ポイントを定義します。
//
 
#include "stdafx.h"
#include <stdlib.h>    // wcstombs_s
#include <locale.h>    // setlocale
#include <string.h>    // strlen
#include <errno.h>
 
int wchartToChar ( const wchar_t* pSrc
                 , char*          pDest
                 , const size_t   iDestSize
                 );
int charToWchart ( const char*  pSrc
                 , wchar_t*     pDest
                 , const size_t sDestSize
                 );

int _tmain( int argc, _TCHAR* argv[] )
{
    // ロケール指定
    setlocale( LC_ALL, "Japanese" );

    wchar_t* wcBuf = L"wchar_t メッセージ";

    printf( "(1)変換前\n" );
    printf( "wchar_t:[%S] len:%d byte:%d\n"
          , wcBuf
          , wcslen( wcBuf )
          , sizeof( wcBuf )
          );
    // %sじゃダメ

    // wchar_t* -> char*
    char cBuf[(18*2)+1];
//    char cBuf[256];
    wchartToChar( wcBuf, cBuf, sizeof( cBuf ) );

    printf( "(2)wchar_t=>char変換後\n" );
    printf( "char   :[%s] len:%d byte:%d\n"
          , cBuf
          , strlen( cBuf )
          , sizeof( cBuf )
          );

    // char* -> wchar_t*
    wchar_t wcBuf2[13+1];
    printf( "wcBuf2 sizeof=%d\n", sizeof( wcBuf2 ) );
//    charToWchart( cBuf, wcBuf2, sizeof( wcBuf2 ) );
//    第3パラメータをsizeof( wcBuf2 )=28にすると
//    mbstowcs_sでEILSEQエラーが出る。
//    あくまで文字数を指定しなければならない。

    printf( "cBuf strlen=%d\n", strlen( cBuf ) );
//    charToWchart( cBuf, wcBuf2, strlen( cBuf ) );
//    strlenはマルチバイト文字を2文字と数える
//    そのため「wchar_t メッセージ」は18文字となる。
//    第3パラメータに指定するのはあくまでwchar_tの文字数なので
//    strlen( cBuf )=18もNG。

    charToWchart( cBuf, wcBuf2, 13 );
//    第3パラメータの文字数は終端文字も含む?
//    13だとエラーになる。

    charToWchart( cBuf, wcBuf2, 13+1 );

    printf( "(3)char=>wchar_t変換後\n" );
    printf( "wchar_t:[%S] len:%d byte:%d\n"
          , wcBuf2
          , wcslen( wcBuf2 )
          , sizeof( wcBuf2 )
          );

    getchar();

    return 0;
}
 
//==============================================================
// [概要]
//   wchar_t* から char* への変換を行う
// [引数]
//   pSrc      const wchar_t*  変換するwchar_t型の文字列。
//   pDest     char*           変換結果のchar型文字列。
//   sDestSize const size_t    pDestのサイズ
// [戻り値]
//   int  0:正常,1:異常
//==============================================================
int wchartToChar ( const wchar_t* pSrc
                 , char*          pDest
                 , const size_t   sDestSize
                 )
{
    size_t iReturnValue;
    errno_t ret = wcstombs_s( &iReturnValue
                            , pDest
                            , sDestSize
                            , pSrc
                            , _TRUNCATE
                            );
    if ( ret != 0 )
    {
        printf( "wcstombs_s error!! ret=%d\n", ret );
        return 1;
    }

    printf( "wcstombs_s return value(変換された文字数):%d\n"
          , iReturnValue
          );

    return 0;
}

//==============================================================
// [概要]
//   char* から wchar_t* への変換を行う
// [引数]
//   pSrc      const char*   変換するchar型の文字列。
//   pDest     wchar_t*      変換結果のwchar_t型文字列。
//   sDestSize const size_t  pDestのサイズ
// [戻り値]
//   int  0:正常,1:異常
//==============================================================
int charToWchart ( const char*  pSrc
                 , wchar_t*     pDest
                 , const size_t sDestSize
                 )
{
    printf( "pSrc=[%s] sDestSize=[%d]\n", pSrc, sDestSize );

    size_t iReturnValue;
    errno_t ret = mbstowcs_s( &iReturnValue
                            , pDest
                            , sDestSize
                            , pSrc
                            , _TRUNCATE
                            );
    if ( ret != 0 )
    {
        printf( "mbstowcs_s error!! ret=" );
        switch( ret )
        {
        case EINVAL:  printf( "EINVAL\n" );  break;
        case ERANGE:  printf( "ERANGE\n" );  break;
        case EILSEQ:  printf( "EILSEQ\n" );  break;
        default:
            printf( "other[%d]\n", ret );
            break;
        }
        return 1;
    }

    printf( "mbstowcs_s return value(変換された文字数):%d\n"
          , iReturnValue
          );

    return 0;
}

実行してみます。

(1)変換前
wchar_t:[wchar_t メッセージ] len:13 byte:4
wcstombs_s return value(変換された文字数):19
(2)wchar_t=>char変換後
char   :[wchar_t メッセージ] len:18 byte:37
wcBuf2 sizeof=28
cBuf strlen=18
pSrc=[wchar_t メッセージ] sDestSize=[13]
mbstowcs_s error!! ret=other[80]
pSrc=[wchar_t メッセージ] sDestSize=[14]
mbstowcs_s return value(変換された文字数):14
(3)char=>wchar_t変換後
wchar_t:[wchar_t メッセージ] len:13 byte:28

上手くいきました。

▲ PageTop  ■ Home


Copyright (C) 2012 ymlib.com