0

パラメータとして配列を期待する関数がありwchar_tます。char から への変換を行う標準ライブラリ関数を知らないwchar_tので、簡単な汚い関数を書きましたが、バグや未定義の動作のない信頼できるソリューションが必要です。標準ライブラリには、この変換を行う関数がありますか?

私のコード:

wchar_t *ctow(const char *buf, wchar_t *output)
{
    const char ANSI_arr[]    =  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789`~!@#$%^&*()-_=+[]{}\\|;:'\",<.>/? \t\n\r\f";
    const wchar_t WIDE_arr[] = L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789`~!@#$%^&*()-_=+[]{}\\|;:'\",<.>/? \t\n\r\f";

    size_t n = 0, len = strlen(ANSI_arr);

    while (*buf) {
        for (size_t x = 0; x < len; x++) {
            if (*buf == ANSI_arr[x]) {
                output[n++] = WIDE_arr[x];
                break;
            }
        }
        buf++;
    }
    output[n] = L'\0';
    return output;
}
4

3 に答える 3

1

さて、変換関数はstdlib.h(*) で宣言されています。ただし、latin1 別名 ISO-8859-1 文字セットの文字については、256 未満の Unicode コードの文字が latin1 文字であるため、ワイド文字への変換は単なる割り当てであることを知っておく必要があります。

したがって、最初の文字セットが ISO-8859-1 の場合、変換は次のようになります。

wchar_t *ctow(const char *buf, wchar_t *output) {
 wchar_t cr = output;
    while (*buf) {
        *output++ = *buf++;
    }
    *output = 0;
    return cr;
}

呼び出し元が、変換されたすべての文字を格納するのに十分なサイズの配列へのポインターを渡した場合。

他の文字セットを使用している場合は、icuなどのよく知られたライブラリを使用するか、手動でビルドする必要があります。これは、シングルバイト文字セット (ISO-8859-x セリエ) では簡単ですが、UTF8 などのマルチバイト文字セットではよりトリッキーです。

しかし、処理できるようにしたい文字セットを知らなければ、これ以上は言えません...

ところで、プレーン ascii は ISO-8859-1 文字セットのサブセットです。

(*) cplusplus.comより

int mbtowc (wchar_t* pwc, const char* pmb, size_t max);

マルチバイト シーケンスをワイド文字に変換 pmb が指すマルチバイト文字は wchar_t 型の値に変換され、pwc が指す位置に格納されます。この関数は、マルチバイト文字の長さをバイト単位で返します。

mbtowcには独自の内部シフト状態があり、この関数の呼び出しによってのみ必要に応じて変更されます。null ポインターを pmb として関数を呼び出すと、状態がリセットされます (マルチバイト文字が状態に依存するかどうかが返されます)。

この関数の動作は、選択した C ロケールの LC_CTYPE カテゴリによって異なります。

于 2016-07-03T22:39:43.923 に答える
0

ヘッダー wchar.h で行います。それはbtowcと呼ばれます:

btowc 関数は、c の値が EOF の場合、または (unsigned char)c が初期シフト状態で有効なシングルバイト文字を構成しない場合、WEOF を返します。それ以外の場合は、その文字のワイド文字表現を返します。

于 2016-07-03T22:40:05.967 に答える