【发布时间】:2016-10-11 05:17:11
【问题描述】:
我有一个多字节 Windows 项目,我尝试访问一个文件,该文件的名称可以带有现代 Windows 允许的任何符号。但是如果文件名包含非 ASCII 字符(日语、瑞典语、俄语等),我会惨败。
例如:
const char * filename_ = "C:\\testÖ.txt"
struct _finddata_t fd;
long fh = _findfirst(filename_, &fd);
此时_findfirst() 失败。
在这里支持所有可能的文件名的最佳解决方案是什么?我读到_findfirst() 取决于程序启动时设置的系统区域设置。好吧,我可以为某个文件更改它,但在这种情况下,我如何确定文件名所需的语言环境?
项目必须保持多字节。
以前有人解决过这个问题吗?
我也尝试使用宽字符转换,但也没有运气。下面的代码示例:
debug_prnt("DEBUG: Checking existance of a file: %s\n", filename_);
struct _wfinddata_t ff;
size_t requiredSize = mbstowcs(NULL, filename_, 0);
wchar_t * filename = (wchar_t *)malloc((requiredSize + 1) * sizeof(wchar_t));
if (!filename)
{
debug_prnt("ERROR: Memory allocation failed\n");
return FALSE;
}
size_t size = mbstowcs(filename, filename_, requiredSize + 1);
if (size == (size_t)(-1))
{
debug_prnt("ERROR: Couldn't convert string--invalid multibyte character.\n");
return FALSE;
}
long fh = _wfindfirst(filename, &ff);
if (fh > 0)
debug_prnt("DEBUG: File exists\n");
else
debug_prnt("DEBUG: File does not exist %ls\n", filename);
free(filename);
【问题讨论】:
-
_findfirst()上的文档和变体是 msdn.microsoft.com/en-us/library/zyzxfzac.aspx,在我看来你应该使用_wfindfirst()。一般来说,这些天我坚持使用 UNICODE 和宽字符,因为 Windows API 需要它。你为什么使用strlen()?这意味着您的原始filename_包含char文本而不是wchar_t文本,因此这可能是您的问题所在。 -
strlen 出错了。我已经在 IBM 论坛上找到了正确的长度计算并在此处更新了代码,但我仍然找不到该文件。我也在使用 _wfindfirst 但到目前为止没有运气。
-
这是您使用的实际代码吗?此处的示例 cplusplus.com/reference/cstdlib/mblen 用于
mblen()和mbtowc()显示了对这两个功能的重置,并且执行方式与您正在执行的方式不同。 -
我认为你想改用
mbstowcs()。 cplusplus.com/reference/cstdlib/mbstowcs
标签: c localization