【问题标题】:Convert filesystem::path into char* on windows在 Windows 上将 filesystem::path 转换为 char*
【发布时间】:2019-01-09 11:32:18
【问题描述】:

C++17 filesystem 基于 boost.filesystem。

我现在在带有 VS2017 的 Windows 上使用它。

#include <filesystem>
namespace fs = std::experimental::filesystem;

我遍历一个目录

for (auto& p: fs::directory_iterator("media"))

我想将路径传递给一个将文件路径作为const char *的函数

我发现了一个关于boost filesystem here 的类似问题。 一个核心区别在于path in C++17 基于value_type

value_type:文件系统的本机编码使用的字符类型:POSIX 上的 char,Windows 上的 wchar_t

所以我得到的是一个const wchar_t * 字符串。

以下对我“有效”:

    char file[2000];
    wcstombs(file, p.path().c_str(), 2000);
    auto image = SDL_LoadBMP(file);

我正在寻找一个不同的版本,因为这个实现是各种各样的混乱(衰减数组到指针和 _CRT_SECURE_NO_WARNINGS)。

我正在寻找一个更漂亮的版本,它可以使用 Windows 上的新 C++17 文件系统从路径直接转到 const char *

这是我用来探索这个的 SDL2 项目。

#define _CRT_SECURE_NO_WARNINGS 1
#include <SDL.h>
#include <vector>
#include <filesystem>
namespace fs = std::experimental::filesystem;

int main(int argc, char* argv[])
{
    SDL_Init(SDL_INIT_EVERYTHING);
    auto window = SDL_CreateWindow("Test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 400, SDL_WINDOW_SHOWN);
    auto scrrenSurface = SDL_GetWindowSurface(window);

    auto images = std::vector<SDL_Surface*>();

    for (auto& p: fs::directory_iterator("media"))
    {
        char file[2000];
        wcstombs(file, p.path().c_str(), 2000);
        auto image = SDL_LoadBMP(file);
        images.push_back(image);
    }

    for (auto&image : images)
    {
        SDL_BlitSurface(image, NULL, scrrenSurface, NULL);
        SDL_UpdateWindowSurface(window);
        SDL_Delay(2000);
    }

    for (auto&image : images)
        SDL_FreeSurface(image);

    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
}

编辑: 在评论部分有一个类似的问题链接so-question 这些问题是同一核心问题的不同表现形式,即将路径转换为可以被另一种方法使用的格式。我反对删除这个问题,因为这两个问题都是通过不同的搜索找到的。

【问题讨论】:

  • 应该有一个可以在名为 MAX_PATH 的标头中使用的定义。
  • 可能是stackoverflow.com/q/54007437/560648 的副本?
  • 很遗憾,MAX_PATH 有旧的限制,而不是 32768 UTF-16 编码单元的当前限制。
  • @Eljay 这只是部分正确。至少according to MSDN,一个可以超过MAX_PATH 的限制,仅适用于带有\\?\ 前缀的绝对路径。即便如此,限制也不一定是 32768,而是会少一点……
  • @MichaelKenzel 在同一个 MSDN 页面再往下一点:“从 Windows 10 版本 1607 开始,MAX_PATH 限制已从常见的 Win32 文件和目录函数中删除。但是,您必须选择- 加入新的行为。" 所以如果你选择加入,你就不再需要 \\?\。

标签: c++ c++17


【解决方案1】:

您可以使用std::filesystem::path 对象的*string()generic_*string() 成员函数将路径转换为本机或通用(即POSIX 样式)字符串。例如:

SDL_LoadBMP(p.path().string().c_str());

请注意,这些方法返回一个std::basic_string&lt;T&gt; 值。因此,必须确保,例如,直接在返回值上调用 .c_str() 获得的指针(如上例所示)不会超过它指向的字符串……

【讨论】:

  • 我测试了它,这就是我想要的……现在我需要等待 7 分钟才能接受你的答案。 :)
  • 请注意,返回的字符串是临时的,因此将在完整表达式的末尾被销毁。假设 SDL 不存储指针以供以后使用,此代码可能没问题,但应该让未来的访问者清楚,存储 string().c_str() 以供以后使用是行不通的。
猜你喜欢
  • 2019-01-31
  • 2021-08-21
  • 2013-04-25
  • 1970-01-01
  • 2021-11-18
  • 2018-02-18
  • 1970-01-01
  • 1970-01-01
  • 2012-01-13
相关资源
最近更新 更多