在启用 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()
只是为此目的而编写的函数的占位符。由于这种方法看起来有些笨拙,我首先想征求一些反馈,看看这是否真的是可行的方法,或者我是否遗漏或误解了这里的某些内容...
最佳答案
你的第一个例子是在正确的轨道上,但有几个错误:
您的变量应该声明为
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 codeunit。 wcslen()
计算字符串中 WCHAR
元素的数量,而不是它们代表的 Unicode codepoints 数量,就像您所想的那样。因此,如果给定的 codepoint 需要 UTF-16 代理项对,它将在字符串中使用两个 WCHAR
元素,并且 wcslen()
将数2。否则,它将使用 1 个 WCHAR
并且 wcslen()
将为它计数 1。
对于 strlen()
和 MBCS 字符串也是如此,当给定的 Unicode 代码点在字符串中使用超过 1 个代码单元(char
元素)进行编码时。
关于c - 使用 Unicode 遍历 OFN_ALLOWMULTISELECT 中的所有文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37976710/