错误代码
#include <stdio.h>
#include <iostream>
#include "Windows.h"
using namespace std;
int main(int argc, char* argv[]) {
char* str = argv[1];
char cFilename[256] = { 0 };
HANDLE hFile;
DWORD dwReturn;
sprintf_s(cFilename, "D:\\ws\\tmpdir\\%s.txt", str);
cout << cFilename << endl;
hFile = CreateFile((LPCWSTR)cFilename, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
cout << "hFile=" << hFile << endl;
cout << "INVALID_HANDLE_VALUE=" << INVALID_HANDLE_VALUE << endl;
if (hFile == INVALID_HANDLE_VALUE)
{
cout << "hFile INVALID_HANDLE_VALUE" << endl;
return 1;
}
hFile = INVALID_HANDLE_VALUE;
return 0;
}
上面这段代码在VS2022中,编码格式为GB2312,使用VC++编译,不会报错,但是执行代码不会创建文件。要想明白原因需要看一下 CreateFile 的定义:
WINBASEAPI
HANDLE
WINAPI
CreateFileA(
_In_ LPCSTR lpFileName,
_In_ DWORD dwDesiredAccess,
_In_ DWORD dwShareMode,
_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
_In_ DWORD dwCreationDisposition,
_In_ DWORD dwFlagsAndAttributes,
_In_opt_ HANDLE hTemplateFile
);
WINBASEAPI
HANDLE
WINAPI
CreateFileW(
_In_ LPCWSTR lpFileName,
_In_ DWORD dwDesiredAccess,
_In_ DWORD dwShareMode,
_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
_In_ DWORD dwCreationDisposition,
_In_ DWORD dwFlagsAndAttributes,
_In_opt_ HANDLE hTemplateFile
);
#ifdef UNICODE
#define CreateFile CreateFileW
#else
#define CreateFile CreateFileA
#endif // !UNICODE
由于编译和运行环境的不同,这里会走 #define CreateFile CreateFileW
分支,也就是说第一个参数必须是LPCWSTR。上面的错误例子中,就算把 char* 强制转换成 LPCWSTR,也只是编译器不报错,但是实际运行程序的时候还是无法创建文件。
正确的写法
把 CreateFile 函数替换成 CreateFileA 函数,即可正常创建文件。
#include <stdio.h>
#include <iostream>
#include "Windows.h"
using namespace std;
int main(int argc, char* argv[]) {
char* str = argv[1];
char cFilename[256] = { 0 };
HANDLE hFile;
sprintf_s(cFilename, "D:\\ws\\tmpdir\\%s.txt", str);
cout << cFilename << endl;
hFile = CreateFileA(cFilename, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
cout << "hFile=" << hFile << endl;
cout << "INVALID_HANDLE_VALUE=" << INVALID_HANDLE_VALUE << endl;
if (hFile == INVALID_HANDLE_VALUE)
{
cout << "hFile INVALID_HANDLE_VALUE" << endl;
return 1;
}
hFile = INVALID_HANDLE_VALUE;
return 0;
}