在启用Unicode的OFN_ALLOWMULTISELECT
打开文件对话框中迭代所有文件的推荐方法是什么?
我的第一个想法是这样的:
TCHAR *tmp = ofn.lpStrFile + ofn.nFileOffset;
while(*tmp) {
wprintf("Got file: %s\n", tmp);
tmp += wcslen(tmp) + 1;
}
但后来我发现,如果字符串缓冲区中的字符无法以16位表示,则无法使用。因此,对于安全方法,我首先需要找出tmp
TCHAR
字符串的字节长度,然后将TCHAR
指针强制转换为char
并添加该字节长度在每次迭代中。像这样:
TCHAR *tmp = ofn.lpStrFile + ofn.nFileOffset;
while(*tmp) {
wprintf("Got file: %s\n", tmp);
tmp = (TCHAR *) (((char *) tmp)) + get_byte_len_of_tstr(tmp));
}
请注意,get_byte_len_of_tstr()
只是一个为此目的而编写的函数的占位符。由于这种方法看起来有些笨拙,我首先想问一下这是否真的是要走的路,或者我是否错过了或误解了一些东西......
答案 0 :(得分:2)
你的第一个例子是在正确的轨道上,但有几个错误:
您的变量应声明为WCHAR*
而不是TCHAR*
。
wprintf()
不接受char*
格式字符串作为输入,而是需要wchar_t*
。
WCHAR *tmp = ofn.lpStrFile + ofn.nFileOffset;
while (*tmp)
{
wprintf(L"Got file: %s\n", tmp);
tmp += (wcslen(tmp) + 1);
}
如果你想使用TCHAR
(你真的不应该,除非你需要支持Win9x / ME),那么它将会是这样的:
TCHAR *tmp = ofn.lpStrFile + ofn.nFileOffset;
while (*tmp)
{
_tprintf(_T("Got file: %s\n"), tmp);
tmp += (_tcslen(tmp) + 1);
}
话虽如此,您对wcslen()
的理解是错误的(但您使用它是正确的)。在Windows中,Unicode字符串以UTF-16编码,其中每个WCHAR
元素是UTF-16 代码单元。 wcslen()
计算字符串中WCHAR
个元素的数量,而不是它们所代表的Unicode 代码点的数量,就像您所想的那样。因此,如果给定的代码点需要UTF-16代理项对,它将在字符串中使用两个WCHAR
元素,而wcslen()
将为它计数2。否则,它将使用1 WCHAR
,而wcslen()
将为其计数1。
对于strlen()
和MBCS字符串,当在字符串中使用多于1个codeunit(char
元素)编码给定的Unicode代码点时,情况也是如此。