【问题标题】:Trying to CreateDirectory, getting char* to LPCWSTR error, willing to try another function尝试 CreateDirectory,将 char* 转换为 LPCWSTR 错误,愿意尝试其他功能
【发布时间】:2011-10-24 09:04:18
【问题描述】:

我试过用谷歌搜索这个,根据各种具体情况有很多答案,坦率地说,我比刚开始时更卡住了。

事实是这样的:

  • 语言: C/C++
  • 操作系统: Windows
  • IDE: Visual Studio 2005
  • 我正在尝试使用 CreateDirectory(在 windows.h 的 #include 之后)从程序中的函数创建目录。
  • 假设第一个参数(路径)应该是char*。但是,当我尝试编译时,出现以下错误:error C2664: 'CreateDirectoryW' : cannot convert parameter 1 from 'char *' to 'LPCWSTR'
  • 我读到的是,我在 UNICODE 和 ANSI 之间存在某种问题。解决方案千差万别,我害怕破坏重要的东西,或者做一些非常愚蠢的事情。
  • 我非常愿意使用任何其他方法来创建一个新目录,如果一个存在而无需我找到其他库。
  • 我只辅修了 comp sci,坦率地说,我不知道为什么通过 stdio 打开、关闭、编辑和以其他方式访问文件如此容易,但对目录做任何事情(特别是制作它们并找出它们是否存在)是一场在互联网大街小巷的大雁追逐。

请帮助我,修复当前对 CreateDirectory 的尝试或使用其他东西来创建目录。

谢谢!

【问题讨论】:

    标签: c++ windows winapi create-directory


    【解决方案1】:

    这太疯狂了。微软有机制从同一代码支持 ANSI(他们称之为)和 UNICODE,因为 Windows 95/8/Me 是 ANSI 操作系统,而 NT/XP/Vista 等是 UNICODE 操作系统。因此,如果您真的愿意,您可以编写一组支持两个系统的代码,然后为每个系统重新编译。

    但是谁对 Windows 95/98/Me 感兴趣呢?然而,这些东西会让新手感到困惑。

    这就是问题所在,Windows 中没有名为 CreateDirectory 的函数,有一个名为 CreateDirectoryW 的 UNICODE 函数和一个名为 CreateDirectoryA 的 ANSI 函数。 CreateDirectory 会根据您定义的编译器选项转换为 CreateDirectoryW 或 CreateDirectoryA。如果您最终使用 CreateDirectoryW(正如您显然所做的那样),则必须将 Unicode 字符串传递给它,如果您使用 CreateDirectoryA,则传递普通的 ASCII 字符串。

    在您的情况下,最简单的事情就是忘记所有这些,直接调用 CreateDirectoryA。

    CreateDirectoryA("c:\\some\\directory", NULL);
    

    为什么在 C++ 中创建目录如此困难?我猜是因为在 70 年代 C 还是新语言的时候,并不是每个操作系统都有目录,所以这些东西从来没有成为语言标准。

    【讨论】:

    • 在 Windows XP 上使用 CreateDirectoryA 会破坏什么吗?或者这是可以接受的做法?
    • 在幕后 XP 会将您的 ANSI 字符串转换为 Unicode,因为它只知道 Unicode。如果您开始使用不寻常的字符,可能会有一些惊喜,但即便如此也可能不会。对于完整的故事,您可能需要与真正的专家(我不是)交谈。
    【解决方案2】:

    VS2005 默认是 Unicode,你最好保持这种方式。将来可能会为您节省很多问题。在 Unicode 构建中 CreateDirectory(和其他 Win32 函数)需要 wchar_t 字符串,而不是常规的 char。制作字符串文字 wchar_t's 很简单 -

    L"Some string" 使其始终为 Unicode,或_T("Some string") 使其依赖于配置。

    我不知道你到底是怎么调用CreateDirectory的,但是如果把字符串转换成Unicode太麻烦,你可以直接使用ANSI版本-CreateDirectoryA。如果您想要更详细的答案,请发布一些代码。

    【讨论】:

    • char* path = ("%s%s",TOP_EXPORT_PATH,TOP_EXPORT_FOLDER); CreateDirectory(path,NULL); //this is what I was trying
    • 该代码看起来不正确,但无论如何您都有一个 ASCII 字符串,所以只需调用 CreateDirectoryA。很简单。
    • @Rae,使用wchar_t* path = <the path>; CreateDirectory(path, NULL);。我使用了<the path>,因为您创建字符串的方式是错误的。您可能只想使用std::wstring,或者如果您仅限于C,则使用springtf,但这与原始问题不同......
    • 哦哦。对如何? TOP_EXPORT_PATH 和 TOP_EXPORT_FOLDER 是程序开头的#defines。我会试试 CreateDirectoryA。
    • 看来您认为它将连接 TOP_EXPORT_PATH 和 TOP_EXPORT_FOLDER 字符串。我向你保证它不会那样做。打印出 path 的值来检查你得到了什么。
    【解决方案3】:

    在包含windows.h 之前尝试使用#undef UNICODE。除非你真正编码 Unicode,但那是另一回事。

    在新的 Visual Studio 中,windows.h 默认为 Unicode 版本,因此#undef UNICODE 将返回 ANSI 版本。它将显示在堆栈跟踪中——您将调用CreateDirectoryA 而不是CreateDirectoryW

    或者,直接致电CreateDirectoryA,但不知何故,我觉得这不是最佳做法。

    【讨论】:

    • 我如何知道我是否真的在使用 Unicode?或者这是非常不寻常/故意应用的?
    • 默认情况下你是 Unicode。问题是你想使用 Unicode 吗?这完全取决于你:-) 另外,eran 建议使用_T() 宏也很好。
    • @Andrew,我不会#undef UNICODE。首先,您可能会与看不到undef 的其他编译单元不匹配。其次,还有一个_UNICODE 定义(现在不记得哪个做了什么......)。最后,最好使用常规的configuration 设置这些功能。
    • _T 宏的目的是使您能够同时支持 unicode 和 ansi。除非您想这样做,否则使用它有什么意义?说出你的意思并使用正确的字符串。
    • @eran,你提出了一些非常好的观点,我同意你的看法。我认为最简单的解决方案是在使用CreateDirectoryA 与只使用wchar_t 之间进行折腾。
    猜你喜欢
    • 1970-01-01
    • 2021-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-13
    • 2020-09-10
    • 1970-01-01
    • 2013-04-27
    相关资源
    最近更新 更多