[英]GetFileAttributeW fails for non-ASCII characters
所以我试图检查给定的文件是否存在。 在这个答案后我尝试了GetFileAttributesW
。 它适用于任何ascii输入,但它不能用于ß,ü和á(以及我怀疑的任何其他非ascii字符)。 我为它们获取了文件名的ERROR_FILE_NOT_FOUND
和带有它们的路径名的ERROR_PATH_NOT_FOUND
,正如人们所预期的那样,如果它们不存在的话。
我100%肯定他们做到了。 我花了15分钟来复制文件名,以免拼写错误并使用文字来避免任何不良输入。 我找不到任何错误。
由于所有这些字符都是非ascii字符,我不再尝试,因为我怀疑我可能已经搞砸了编码。 我只是无法发现它。 有什么我想念的吗? 我链接到Kernel32.lib
谢谢!
#include <stdio.h>
#include <iostream>
#include <string>
#include "Windows.h"
void main(){
while(true){
std::wstring file_path;
std::getline(std::wcin, file_path);
DWORD dwAttrib = GetFileAttributesW(file_path.data());
if(dwAttrib == INVALID_FILE_ATTRIBUTES){
printf("error: %d\n", GetLastError());
continue;
}
if(!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY))
printf("valid!\n");
else
printf("invalid!\n");
}
}
在Windows上的控制台程序中使Unicode工作得很好是非常困难的,所以让我们首先去掉它的这个方面(现在)。
修改您的程序,使其如下所示:
#include <cstdio>
#include <iostream>
#include <string>
#include "Windows.h"
int main() {
std::wstring file_path = L"fooß.txt";
DWORD dwAttrib = GetFileAttributesW(file_path.data());
if (dwAttrib == INVALID_FILE_ATTRIBUTES)
printf("error: %d\n", GetLastError());
if (!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY))
printf("valid!\n");
else
printf("invalid!\n");
return 0;
}
即使您使用的是UTF-8,也要确保使用字节顺序标记(BOM)保存此文件。 Windows应用程序,包括Visual Studio和编译器,可能非常挑剔。 如果编辑器不这样做,请使用Visual Studio编辑文件,然后使用“另存为”,单击“保存”按钮旁边的向下箭头,选择“使用编码”。 在“高级保存选项”对话框中,选择“Unicode(带签名的UTF-8) - 代码页65001”。
确保当前文件夹中有一个名为fooß.txt
的文件。 我强烈建议使用GUI程序来创建此文件,如记事本或资源管理器。
这个程序有效。 如果仍然收到文件未找到消息,请检查以确保临时文件位于工作目录中或更改程序以使用绝对路径。 如果使用绝对路径,请使用反斜杠并确保它们都已正确转义。 检查拼写错误,扩展名等。此代码确实有效。
现在,如果从标准输入中获取文件名:
std::wstring file_path;
std::getline(std::wcin, file_path);
你在控制台窗口中输入fooß.txt
,你可能会发现它不起作用。 如果你查看调试器,你会看到应该是ß
的字符是别的东西。 对我来说,它是á
,但如果您的控制台代码页是其他的话,它可能会有所不同。
ß
是Unicode中的U + 00DF。 在Windows 1252(美国Windows用户最常见的代码页)中,它是0xDF,因此看起来似乎没有转换问题的可能性。 但控制台窗口(默认情况下)使用OEM代码页。 在美国,常见的OEM代码页是437.因此,当我尝试在控制台中键入ß
时,实际上编码为0xE1。 惊喜! 这与á
的Unicode值相同。 如果您设法输入值为0xDF的字符,您将看到对应于您在原始问题中报告的块字符。
你会认为(好吧, 我认为)从std::wcin
请求输入会做任何必要的转换。 但它没有,并且可能存在一些传统的向后兼容性原因。 您可以尝试使用“正确的”代码页填充流,但这变得复杂,我从未打扰过尝试使其工作。 我只是停止尝试在控制台上使用除ASCII以外的任何东西。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.