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 aka 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有自己的内部移位状态,只有通过调用此函数才能根据需要进行更改。使用空指针作为 pmb 调用函数会重置状态(并返回多字节字符是否与状态相关)。

此函数的行为取决于所选 C 语言环境的 LC_CTYPE 类别。

于 2016-07-03T22:39:43.923 回答
0

这不是从wchar_tto的转换char。它是用于破坏 ISO-646 之外的数据的功能。C 库中的任何方法都不会为您进行这种转换。您可以查看 ICU4C 库。如果你只是在 Windows 上,你可以查看 Win32 API 中的相关函数(WideCharToMultiByte 等)。

于 2016-07-03T22:12:39.913 回答
0

它在头文件 wchar.h 中执行。它被称为 btowc:

如果 c 的值为 EOF 或 (unsigned char)c 在初始移位状态中不构成有效的单字节字符,则 btowc 函数返回 WEOF。否则,它返回该字符的宽字符表示。

于 2016-07-03T22:40:05.967 回答