【发布时间】:2018-04-08 07:26:23
【问题描述】:
所以我正在尝试检查给定文件是否存在。在this 回答之后,我尝试了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");
}
}
【问题讨论】:
-
使用文字来避免任何错误的输入。 -- 这是否意味着您在源代码中输入了字符?我认为这不是一个好主意,因为您不知道编译器对该字符文字做了什么。不如先写一个小的
FindFirstFile / NextFile程序,看看你会得到什么?然后获取返回的文件名并在该名称上调用GetFileAttributes。 -
stdio.h和朋友是旧的 C 兼容标头 - 改用cstdio和朋友。 -
以这种方式尝试(使用常量 Unicode 字符串)
DWORD dwAttrib = GetFileAttributesW( L"c:\\dir\\your_ß_file" );。如果有效,则问题出在wstring转换或getline。 -
@PaulMcKenzie “不知道编译器对那个字符文字做了什么”:当然,你知道。您为源代码使用您选择的特定字符编码,将其告知编译器,并告诉编译器将其转换为哪种编码。 (请参阅此answer。)即使您使用编译器的默认值,这也不是一个选项。
-
@PaulMcKenzie 我使用您建议的
FindFirstFile / NextFile方法为自己找到了有问题的文件名。应该/是“ß”的字符在输出中是“▀”(我希望它可以显示在网站上)这看起来不像是通用的“我不知道”,而是特定的unicode特点。如果我使用这个文件名作为程序的输入,一切正常。我仍然不知道为什么这是一个与预期不同的角色。
标签: c++ file wchar-t wstring kernel32