V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
archdevil
V2EX  ›  程序员

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

  •  
  •   archdevil · Jul 29, 2017 · 4042 views
    This topic created in 3203 days ago, the information mentioned may be changed or developed.
    我有一个文件,D:\x・x\1.txt
    x 与 x 之间那个点是全角符号,我试了很多 API 都无法识别这个路径
    fopen, CFindFile,GetFileAttributesW 等函数都尝试过,都无法识别路径。
    请问要怎么解决这个编码问题
    19 replies    2017-07-30 10:36:28 +08:00
    auser
        1
    auser  
       Jul 29, 2017   ❤️ 1
    貌似是 Windows 环境下的,不懂,胡乱猜测一下:源代码文件编码经过编译后的表示跟 FileSystem 用的不一样导致的吧。
    正解:从源头上解决这个问题,文件名用普通常用模式。
    alqaz
        2
    alqaz  
       Jul 29, 2017
    可以改文件名吗?还有,如果文件名写在代码里,试着看下代码的编码。
    archdevil
        3
    archdevil  
    OP
       Jul 29, 2017
    我知道改文件名就行了,可是我就是想知道 windows 下的 vs 编译器里怎么解决这个问题。
    windows 自身能识别这些目录和文件,为什么他提供的 API 就不行呢
    veelog
        4
    veelog  
       Jul 29, 2017 via iPhone
    试试遍历目录,把这个文件名二进制数据发音,出来,在打印你自己定义的文件名对比下
    nifury
        5
    nifury  
       Jul 29, 2017
    fopen 或许是对 unicode 支持不好吧,毕竟是 ansi 版本
    GetFileAttributesW 和 CreateFileW 是可以的
    Librazy
        6
    Librazy  
       Jul 29, 2017
    GetFileAttributesExW + \\?\ 试试?
    wevsty
        7
    wevsty  
       Jul 29, 2017
    跟楼上说的一样,用 Unicode 版本的 API,你这个估计是编码的问题。
    可以用 API 枚举一下文件夹,然后看看枚举出来的路径和你自己输入的有什么区别
    hobochen
        8
    hobochen  
       Jul 29, 2017 via Android
    windows 下的路径为 UTF-16 编码
    ysc3839
        9
    ysc3839  
       Jul 29, 2017 via Android
    Win 下 fopen 是 ANSI 的,肯定不行。换用 wfopen (不知有没有记错),或者 CreateFileW。另外试试把代码文件保存成 UTF-8 编码。
    RLib
        10
    RLib  
       Jul 29, 2017
    楼上的, 注意 LZ 说的 GetFileAttributesW 已经就是宽字符版本了
    baixiangcpp
        11
    baixiangcpp  
       Jul 29, 2017
    @ysc3839 用了 ANSI,当然存为 GBK 啊
    baixiangcpp
        12
    baixiangcpp  
       Jul 29, 2017
    字符串字面量编码是你源文件的编码。

    1.路径编码是 GBK 的话,就用 ANSI 的函数 fopen,CreateFile
    2.路径编码是 Unicode ( UCS2 ) 的话,就用 CreateFileW
    3.utf-8 保存的话,glib 的那套函数是 utf8 版本的
    ysc3839
        13
    ysc3839  
       Jul 29, 2017
    @baixiangcpp GBK 编码可能没有这个字符
    FanWall
        14
    FanWall  
       Jul 29, 2017
    一律用宽字符就好了
    ysc3839
        15
    ysc3839  
       Jul 29, 2017
    #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
        16
    baixiangcpp  
       Jul 30, 2017
    @ysc3839 你知道 fopen 是 ANSI 的函数,还用 UTF8 保存,这不是故意的找错吗
    yksoft1
        17
    yksoft1  
       Jul 30, 2017
    你碰上了 GBK 编码的缺陷之一(不支持日文编码中的那个点以及半角片假名)。这种情况 ANSI 版的 fopen 是不能用的。
    soratadori
        18
    soratadori  
       Jul 30, 2017
    我想说......请注意你的 cpp 文件编码格式,你要想用 wfopen 之类的支持 unicode 的函数,你传进去的字符也必须是 unicode。
    RLib
        19
    RLib  
       Jul 30, 2017   ❤️ 1
    这贴怎么又上来了...
    @baixiangcpp 编码用 UTF8 保存并没有错, 还能保证跨平台不出问题, 楼主的例子在于如果不保存成 UTF 系列编码一开始信息就丢失了, 编译器读到的只是 0x3f 这一个字节.
    另外编译器编译时会完成转换, 最后和源文件编码无关:
    "・" 编译后无论源码是什么格式都是 ANSI 编码, 在 ANSI 被设定 936 的情况下它是 0x3f
    L"・" UTF-16 编码
    u8"・" UTF-8 编码
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5703 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 72ms · UTC 06:48 · PVG 14:48 · LAX 23:48 · JFK 02:48
    ♥ Do have faith in what you're doing.