wcrtomb() — ワイド文字からマルチバイト文字への変換 (再開可能)

形式

#include <wchar.h>
size_t wcrtomb (char *s, wchar_t wc, mbstate_t *ps);

言語レベル

ANSI

スレッド・セーフ

ps が NULL の場合を除いて、対応しています。

ロケール依存

この関数の振る舞いは、現行ロケールの LC_CTYPE カテゴリーの影響を受ける可能性があります。 また、この振る舞いは、LOCALETYPE(*LOCALEUCS2) または LOCALETYPE(*LOCALEUTF) がコンパイル・コマンドに対して指定されている場合は、現行ロケールの LC_UNI_CTYPE カテゴリーの影響を受ける可能性もあります。 この関数は、コンパイル・コマンドに対して LOCALETYPE(*CLD) が指定されている場合には使用できません。 詳しくは、 CCSID とロケールについてを参照してください。

ワイド文字関数

詳しくは、 ワイド文字 を参照してください。

説明

この関数は、 wctomb() 関数の再始動可能バージョンです。

wcrtomb() 関数は、ワイド文字をマルチバイト文字に変換します。

s が NULL ポインターの場合、 wcrtomb() 関数は初期シフト状態に入るために必要なバイト数を判別します (エンコードが状態依存でない場合、または初期変換状態が記述されている場合は、ゼロになります)。 記述されている結果の状態は、初期変換状態です。

s が NULL ポインターでない場合、 wcrtomb() 関数は、 wc によって指定されたワイド文字 (シフト・シーケンスを含む) に対応するマルチバイト文字を表すために必要なバイト数を判別し、その結果のバイトを、 sが指す最初のエレメントを持つ配列に保管します。 最大で、MB_CUR_MAX バイトが保管されます。 wc がヌル・ワイド文字の場合には、 記述されている結果の状態は初期変換状態です。

この関数は、対応する内部状態のマルチバイト文字関数とは以下の点で異なります。 この関数には追加のパラメーターとして mbstate_t の型を指す ps ポインター があり、このポインターは、関連するマルチバイト文字シーケンスの現在の変換状態を完全に表すことができる オブジェクトを指します。 ps が NULL の場合、変換状態の追跡を継続するために内部静的変数が 使用されます。 内部静的変数の使用はスレッド・セーフではありません。

戻り値

s が NULL ポインターの場合、 wcrtomb() 関数は初期シフト状態に入るのに必要なバイト数を戻します。 戻された値は、 MB_CUR_MAX マクロの値より大きくなりません。

s がヌルポインタでない場合、wcrtomb() 関数は、wc が有効なワイド文字のとき、配列オブジェクトに格納されているバイト数 (シフトシーケンスを含む) を返す;そうでない場合 (wc が有効なワイド文字でない場合)、エンコードエラーが発生し、マクロ EILSEQ の値が errno に格納され、-1 が返されるが、変換状態は変更されない。

変換エラーが発生した場合、errnoECONVERT に設定される可能性があります。

このプログラムは LOCALETYPE(*LOCALE) および SYSIFCOPT(*IFSIO) でコンパイルされています。
#include <stdio.h>
#include <locale.h>
#include <wchar.h>
#include <errno.h>

#define  STRLENGTH   10
#define  LOCNAME     "/qsys.lib/JA_JP.locale"
#define  LOCNAME_EN  "/qsys.lib/EN_US.locale"

int main(void)
{
    char      string[STRLENGTH];
    int length, sl = 0;
    wchar_t   wc = 0x4171;
    wchar_t   wc2 = 0x00C1;
    wchar_t  wc_string[10];
    mbstate_t ps = 0;
    memset(string, '\0', STRLENGTH);
    wc_string[0] = 0x00C1;
    wc_string[1] = 0x4171;
    wc_string[2] = 0x4172;
    wc_string[3] = 0x00C2;
    wc_string[4] = 0x0000;
    /* In this first example we will convert a wide character */
    /* to a single byte character.  We first set the locale   */
    /* to a single byte locale.  We choose a locale with      */
    /* CCSID 37.  For single byte cases the state will always */
    /* remain in the initial state  0       */

    if (setlocale(LC_ALL, LOCNAME_EN) == NULL)
        printf("setlocale failed.\n");

    length = wcrtomb(string, wc, &ps);

    /* In this case since wc > 256 hex, lenth is -1 and  */
    /* errno is set to EILSEQ (3492)  */
    printf("errno = %d, length = %d\n\n", errno, length);

    length = wcrtomb(string, wc2, &ps);

    /* In this case wc2 00C1 is converted to C1  */

    printf("string = %s\n\n", string);

    /* Now lets try a multibyte example.  We first must set the */
    /* locale to a multibyte locale.  We choose a locale with     */
    /* CCSID 5026  */

    if (setlocale(LC_ALL, LOCNAME) == NULL)
        printf("setlocale failed.\n");

    length = wcrtomb(string, wc_string[0], &ps);

    /* The first character is < 256 hex so is converted to   */
    /* single byte and the state is still the initial state 0  */

    printf("length = %d, state = %d\n\n", length, ps);

    sl += length;

    length = wcrtomb(&string[sl], wc_string[1], &ps);

    /* The next character is > 256 hex so we get a shift out   */
    /* 0x0e followed by the double byte character.  State is   */
    /* changed to double byte state.  Length is 3.             */

    printf("length = %d, state = %d\n\n", length, ps);

    sl += length;

    length = wcrtomb(&string[sl], wc_string[2], &ps);

    /* The next character is > 256 hex so we get another       */
    /* double byte character.   The state is left in           */
    /* double byte state.  Length is 2.                        */

    printf("length = %d, state = %d\n\n", length, ps);

    sl += length;

    length = wcrtomb(&string[sl], wc_string[3], &ps);

    /* The next character is < 256 hex so we close off the     */
    /* double byte characters with a shift in 0x0f and then    */
    /* get a single byte character.  Length is 2.              */
    /* The hex look at string would now be:                    */
    /* C10E417141720FC2                                        */
    /* You would need a device capable of displaying multibyte */
    /* characters to see this string.                          */

    printf("length = %d, state = %d\n\n", length, ps);

    /* In the last example we will show what happens if NULL   */
    /* is passed in for the state.                             */
    memset(string, '\0', STRLENGTH);

    length = wcrtomb(string, wc_string[1], NULL);

    /* The second character is > 256 hex so a shift out       */
    /* followed by the double character is produced but since  */
    /* the state is NULL, the double byte character is closed  */
    /* off with a shift in right away.  So string we look      */
    /* like this:  0E41710F  and length is 4 and the state is  */
    /* left in the initial state.                              */

    printf("length = %d, state = %d\n\n", length, ps);

}
/*  The output should look like this:

errno = 3492, length = -1

string = A

length = 1, state = 0

length = 3, state = 2

length = 2, state = 2

length = 2, state = 0

length = 4, state = 0
                                   */
このプログラムは LOCALETYPE(*LOCALEUCS2) および SYSIFCOPT(*IFSIO) でコンパイルされています。
#include <stdio.h>
#include <locale.h>
#include <wchar.h>
#include <errno.h>

#define  STRLENGTH   10
#define  LOCNAME     "/qsys.lib/JA_JP.locale"
#define  LOCNAME_EN  "/qsys.lib/EN_US.locale"

int main(void)
{
    char      string[STRLENGTH];
    int length, sl = 0;
    wchar_t   wc = 0x4171;
    wchar_t   wc2 = 0x0041;
    wchar_t  wc_string[10];
    mbstate_t ps = 0;
    memset(string, '\0', STRLENGTH);
    wc_string[0] = 0x0041;
    wc_string[1] = 0xFF31;
    wc_string[2] = 0xFF32;
    wc_string[3] = 0x0042;
    wc_string[4] = 0x0000;
    /* In this first example we will convert a UNICODE character */
    /* to a single byte character.  We first set the locale   */
    /* to a single byte locale.  We choose a locale with      */
    /* CCSID 37.  For single byte cases the state will always */
    /* remain in the initial state  0       */

    if (setlocale(LC_ALL, LOCNAME_EN) == NULL)
        printf("setlocale failed.\n");

    length = wcrtomb(string, wc2, &ps);

    /* In this case wc2 0041 is converted to C1  */
    /* 0041 is UNICODE A, C1 is CCSID 37 A       */

    printf("string = %s\n\n", string);

    /* Now lets try a multibyte example.  We first must set the */
    /* locale to a multibyte locale.  We choose a locale with     */
    /* CCSID 5026  */

    if (setlocale(LC_ALL, LOCNAME) == NULL)
        printf("setlocale failed.\n");

    length = wcrtomb(string, wc_string[0], &ps);

    /* The first character UNICODE character is converted to a */
    /* single byte and the state is still the initial state 0  */

    printf("length = %d, state = %d\n\n", length, ps);

    sl += length;

    length = wcrtomb(&string[sl], wc_string[1], &ps);

    /* The next UNICODE character is converted to a shift out   */
    /* 0x0e followed by the double byte character.  State is   */
    /* changed to double byte state.  Length is 3.             */

    printf("length = %d, state = %d\n\n", length, ps);

    sl += length;

    length = wcrtomb(&string[sl], wc_string[2], &ps);

    /* The UNICODE character is converted to another       */
    /* double byte character.   The state is left in           */
    /* double byte state.  Length is 2.                        */

    printf("length = %d, state = %d\n\n", length, ps);

    sl += length;

    length = wcrtomb(&string[sl], wc_string[3], &ps);

    /* The next UNICODE character converts to single byte so   */
    /* we close off the                                        */
    /* double byte characters with a shiftin 0x0f and then     */
    /* get a single byte character.  Length is 2.              */
    /* The hex look at string would now be:                    */
    /* C10E42D842D90FC2                                        */
    /* You would need a device capable of displaying multibyte */
    /* characters to see this string.                          */

    printf("length = %d, state = %d\n\n", length, ps);


}
/*  The output should look like this:

string = A

length = 1, state = 0

length = 3, state = 2

length = 2, state = 2

length = 2, state = 0
                                   */                            

関連情報