请教一个 C++操作文件的问题

2017-07-29 19:04:04 +08:00
 archdevil
我有一个文件,D:\x・x\1.txt
x 与 x 之间那个点是全角符号,我试了很多 API 都无法识别这个路径
fopen, CFindFile,GetFileAttributesW 等函数都尝试过,都无法识别路径。
请问要怎么解决这个编码问题
3531 次点击
所在节点    程序员
19 条回复
auser
2017-07-29 19:15:23 +08:00
貌似是 Windows 环境下的,不懂,胡乱猜测一下:源代码文件编码经过编译后的表示跟 FileSystem 用的不一样导致的吧。
正解:从源头上解决这个问题,文件名用普通常用模式。
alqaz
2017-07-29 19:15:58 +08:00
可以改文件名吗?还有,如果文件名写在代码里,试着看下代码的编码。
archdevil
2017-07-29 19:24:04 +08:00
我知道改文件名就行了,可是我就是想知道 windows 下的 vs 编译器里怎么解决这个问题。
windows 自身能识别这些目录和文件,为什么他提供的 API 就不行呢
veelog
2017-07-29 19:29:09 +08:00
试试遍历目录,把这个文件名二进制数据发音,出来,在打印你自己定义的文件名对比下
nifury
2017-07-29 19:36:26 +08:00
fopen 或许是对 unicode 支持不好吧,毕竟是 ansi 版本
GetFileAttributesW 和 CreateFileW 是可以的
Librazy
2017-07-29 19:58:42 +08:00
GetFileAttributesExW + \\?\ 试试?
wevsty
2017-07-29 20:19:48 +08:00
跟楼上说的一样,用 Unicode 版本的 API,你这个估计是编码的问题。
可以用 API 枚举一下文件夹,然后看看枚举出来的路径和你自己输入的有什么区别
hobochen
2017-07-29 20:23:15 +08:00
windows 下的路径为 UTF-16 编码
ysc3839
2017-07-29 20:24:13 +08:00
Win 下 fopen 是 ANSI 的,肯定不行。换用 wfopen (不知有没有记错),或者 CreateFileW。另外试试把代码文件保存成 UTF-8 编码。
RLib
2017-07-29 20:26:46 +08:00
楼上的, 注意 LZ 说的 GetFileAttributesW 已经就是宽字符版本了
baixiangcpp
2017-07-29 20:43:13 +08:00
@ysc3839 用了 ANSI,当然存为 GBK 啊
baixiangcpp
2017-07-29 20:50:02 +08:00
字符串字面量编码是你源文件的编码。

1.路径编码是 GBK 的话,就用 ANSI 的函数 fopen,CreateFile
2.路径编码是 Unicode ( UCS2 ) 的话,就用 CreateFileW
3.utf-8 保存的话,glib 的那套函数是 utf8 版本的
ysc3839
2017-07-29 21:24:20 +08:00
@baixiangcpp GBK 编码可能没有这个字符
FanWall
2017-07-29 21:25:53 +08:00
一律用宽字符就好了
ysc3839
2017-07-29 21:30:11 +08:00
#include <stdio.h>
#include <wchar.h>

int main()
{
FILE *f = fopen("C:\\Users\\Richard\\Desktop\\x・x\\1.txt", "r");
printf("0x%X\n", f);
if (f)
fclose(f);

f = _wfopen(L"C:\\Users\\Richard\\Desktop\\x・x\\1.txt", L"r");
printf("0x%X\n", f);
if (f)
fclose(f);
return 0;
}

Output:
0x0
0x1014FF0
baixiangcpp
2017-07-30 01:19:19 +08:00
@ysc3839 你知道 fopen 是 ANSI 的函数,还用 UTF8 保存,这不是故意的找错吗
yksoft1
2017-07-30 01:21:46 +08:00
你碰上了 GBK 编码的缺陷之一(不支持日文编码中的那个点以及半角片假名)。这种情况 ANSI 版的 fopen 是不能用的。
soratadori
2017-07-30 03:53:34 +08:00
我想说......请注意你的 cpp 文件编码格式,你要想用 wfopen 之类的支持 unicode 的函数,你传进去的字符也必须是 unicode。
RLib
2017-07-30 10:36:28 +08:00
这贴怎么又上来了...
@baixiangcpp 编码用 UTF8 保存并没有错, 还能保证跨平台不出问题, 楼主的例子在于如果不保存成 UTF 系列编码一开始信息就丢失了, 编译器读到的只是 0x3f 这一个字节.
另外编译器编译时会完成转换, 最后和源文件编码无关:
"・" 编译后无论源码是什么格式都是 ANSI 编码, 在 ANSI 被设定 936 的情况下它是 0x3f
L"・" UTF-16 编码
u8"・" UTF-8 编码

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/378890

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX