作者xavier13540 (柊 四千)
看板C_and_CPP
标题[问题] CreateFile()回传INVALID_HANDLE_VALUE
时间Fri Aug 25 15:54:42 2023
开发平台(Platform): (Ex: Win10, Linux, ...)
Win11
编译器(Ex: GCC, clang, VC++...)+目标环境(跟开发平台不同的话需列出)
VC++
额外使用到的函数库(Library Used): (Ex: OpenGL, ...)
无
问题(Question):
我最近在用Johnson M. Hart的书学windows的系统程式设计
书上给出了这份使用CreateFile()的程式码 简单实作linux上的cp指令
https://ideone.com/P9q9SD
我用vs2022新增c++ project 加入这份code 按ctrl+F5编译後 总是找不到名称同argv[1]的
档案
https://i.imgur.com/0255HCz.png
我做了两个实验
1.
在这份code里面加入几行得到
https://ideone.com/7muAkc
预期这份新的code会先写一些东西进argv[2]
但重新ctrl+F5後 会发现argv[2]本身变成乱码
https://i.imgur.com/9EUnaHa.png
2.
不用ctrl+F5而是直接用cl.exe编译 结果一切符合预期
https://i.imgur.com/PgLEPRF.png
请问可能的原因是什麽?
我用的是日文版的windows 11 不过我想中文版的应该也会有类似的问题@@
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 111.240.166.90 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1692950091.A.DCC.html
2F:→ nh60211as: 更正,错误码是什麽 08/25 18:35
你说GetLastError()的回传值吗? 是2 查了一下是非常简单的file not found
3F:→ L4ys: Visual Studio project default 会使用 Unicode 版本的 08/25 21:27
4F:→ L4ys: Windows API, 所以其实呼叫的是 CreateFileW, 专案设定里面 08/25 21:27
5F:→ L4ys: 可以修改 08/25 21:28
改成"Use Multi-Byte Character Set"後总算解决了 谢谢
https://i.imgur.com/K6JFuwZ.png
https://i.imgur.com/KEgTjSG.png
另外我发现"Not Set"也可以 只有"Use Unicode Character Set"会坏掉
6F:→ stupid0319: 输入是utf-8,应该转成utf-32喂给windows 08/26 08:51
7F:→ stupid0319: a.txt的utf-32会变两倍大 08/26 08:57
※ 编辑: xavier13540 (111.240.164.124 台湾), 08/26/2023 09:17:12
8F:→ stupid0319: Use Multi-Byte Character Set後,档名有日文怎麽办 08/26 10:41
我刚刚试了一下 用MBCS就算档名有日文也可以正常执行
https://i.imgur.com/k0FrApp.png
反倒是用Unicode的话 连a.txt也会坏掉
不过windows似乎建议新的软体开发都用Unicode 至於MBCS只用来处理legacy code
https://i.imgur.com/xeaw8Dj.png
我觉得还是要想办法让我用Unicode编译後也能成功才是
※ 编辑: xavier13540 (111.240.164.124 台湾), 08/26/2023 17:25:43
9F:推 stupid0319: iconv, code page, unicode 可以好好研究 08/26 17:27
10F:→ stupid0319: 不是unicode坏掉,而是你还没搞懂文字编码 08/26 17:29
11F:→ L4ys: main的argv都是char**,不该用LPTSTR,正确做法是改用wmain 08/26 18:57
12F:→ L4ys: 或是呼叫GetCommandLine/CommandLineToArgv 08/26 18:58
13F:推 L4ys: 或是用_tmain配合LPTSTR argv[] 08/26 19:01
发现在我的机器上 如果定义了UNICODE和_UNICODE这两个macro LPTSTR是wchar_t*的别名
// LPTSTR -> LPWSTR -> WCHAR* -> wchar_t*
如果这两个macro没有被定义 LPTSTR会变成是char*的别名
// LPTSTR -> LPSTR -> CHAR* -> char*
只要把那两个macro undefine掉 或者把main改成wmain 执行结果就正常了
书上第二章就有个interlude在介绍unicode 提到了这两个macro 并引入了_tmain
简单看了一下後面的example code main()都被替换成_tmain()了
※ 编辑: xavier13540 (111.240.164.124 台湾), 08/26/2023 20:09:55
14F:推 LPH66: MSVC 里一部份带 _t 的字串"函数"就是为了这个设定加的 08/27 03:28
15F:→ LPH66: (这些会在 <tchar.h> 里) 当有定义 UNICODE 时它处理宽字元 08/27 03:29
16F:→ LPH66: 当没有定义时它是处理 char 字串 08/27 03:29
17F:→ LPH66: 当有定义 MBCS 时它会变成 _mb 开头的字串处理函数 08/27 03:29
18F:→ LPH66: 主要是用在同一支原始码分别编出 char 字串跟 wchar_t 字串 08/27 03:31
19F:→ LPH66: (以及如果要的话 MBCS 字串) 不同版本时在用的 08/27 03:32
20F:→ LPH66: 那 main 本身有个字串(阵列)参数, 所以也会有 _t 版本 08/27 03:32
21F:→ LPH66: (这就是上面提的 _tmain 的由来) 08/27 03:32
22F:推 LPH66: 啊对对, LP"T"STR 的这个 T 也是 <tchar.h> 这个 t 的意思 08/27 03:43
23F:推 lwecloud: 2023了,不是历史共业的话,直接用UNICODE吧 08/28 14:17
24F:→ lwecloud: 你用MBCS是因为你日文系统,喂一个中文档名就挂了 08/28 14:22