【发布时间】:2015-04-10 08:05:18
【问题描述】:
我正在尝试确保我在 UTF-8 和 UTF-16 之间转换的代码在空终止符方面是正确的。
在MultiByteToWideChar() 的情况下,我知道如果您传递的输出缓冲区大小为 0,您将获得包括终止空值的字符数。我的问题是:您是否将计数 包括 终止 null 作为您的新缓冲区大小,并与计数 包括 终止 null 进行比较?或者换句话说,这是正确的吗?
n = MultiByteToWideChar(..., NULL, 0);
if (MultiByteToWideChar(..., buf, n) != n) error();
我从输入缓冲区大小下的简介中猜测
如果此参数设置为正整数,则函数会精确处理指定的字节数。如果提供的大小不包含终止空字符,则生成的 Unicode 字符串不会以空字符终止,并且返回的长度不包含此字符。
输入缓冲区大小为-1,答案是肯定的;是这样吗?
对于WideCharToMultiByte(),我完全不确定空终止符。如果我为输出缓冲区计数传递 0,返回的计数是否包含空终止符?对于实际转换,我是否说输出缓冲区的大小包括空终止符?返回值是否包含空终止符?
我当前的代码用 no、no 和 no(分别)回答这些问题。这似乎可行,但我宁愿不相信偶然工作的代码。我唯一的提示是以下内容:
如果此参数为 -1,则函数处理整个输入字符串,包括终止空字符。因此,生成的字符串有一个终止空字符,函数返回的长度包括这个字符。
所以我认为答案是肯定的,是的,是的,但我仍然不完全确定。
谢谢。
为了更好的衡量,这是我的代码:
// note: assume logLastError() calls DebugBreak() and that uiAlloc() aborts on failure
#define MBTWC(str, wstr, bufsiz) MultiByteToWideChar(CP_UTF8, 0, str, -1, wstr, bufsiz)
WCHAR *toUTF16(const char *str)
{
WCHAR *wstr;
int n;
n = MBTWC(str, NULL, 0);
if (n == 0)
logLastError("error figuring out number of characters to convert to in toUTF16()");
wstr = (WCHAR *) uiAlloc(n * sizeof (WCHAR), "WCHAR[]");
// TODO verify return includes null terminator
if (MBTWC(str, wstr, n) != n)
logLastError("error converting from UTF-8 to UTF-16 in toUTF16()");
return wstr;
}
#define WCTMB(wstr, str, bufsiz) WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, bufsiz, NULL, FALSE)
char *toUTF8(const WCHAR *wstr)
{
char *str;
int n;
n = WCTMB(wstr, NULL, 0);
if (n == 0)
logLastError("error figuring out number of characters to convert to in toUTF8()");
// TODO does n include the null terminator?
str = (char *) uiAlloc((n + 1) * sizeof (char), "char[]");
if (WCTMB(wstr, str, n + 1) != n)
logLastError("error converting from UTF-16 to UTF-8 in toUTFF8()");
return str;
}
【问题讨论】: