2

Is it me, or does boost::filesystem::path::make_preferred not convert "\" to "/"?

davidan@kempt:~/Documents/prog/work!$ ../practice/./path_info c:\pitou foo/bar\baa.txt
composed path:
cout << -------------: "c:pitou/foo/bar\baa.txt"
make_preferred()----------: "c:pitou/foo/bar\baa.txt"

I was rather hoping for

c:\pitou\foo\bar\baa.txt

on windows and

/pitou/foo/bar/baa.txt

(or something close) on POSIX

the source is here: boost::filesystem tutorial

4

3 回答 3

3

在 Linux 上没有处理它的原因在这里很好地解释了:

http://theboostcpplibraries.com/boost.filesystem-paths

引用:

如果在 Linux 上执行 Example 35.5,返回的值是不同的。大多数成员函数返回一个空字符串,除了 relative_path() 和 filename(),它们返回“C:\Windows\System”。这意味着字符串“C:\Windows\System”在 Linux 上被解释为文件名,这是可以理解的,因为它既不是路径的可移植编码,也不是 Linux 上依赖于平台的编码。因此,Boost.Filesystem 只能将其解释为文件名。

于 2016-06-26T14:59:10.727 回答
2

最终这样做了:

string f = filename;
#       ifdef BOOST_POSIX_API   //workaround for user-input files
            std::replace(f.begin(), f.end(), '\\', '/');        
#       endif

必须有一个原因为什么尚未处理......?

于 2013-05-15T14:16:02.063 回答
0

这不使用boost,但我手动实现了两个转换方向。

FileSystemPathUtils.hpp

#pragma once

#include <string>

static const char *const WSL_FILE_PATH_HEADER = "/mnt";
static const char WINDOWS_FILE_PATH_SEPARATOR = '\\';
static const char UNIX_FILE_PATH_SEPARATOR = '/';

std::string windows_to_unix_file_path(std::string file_path, bool is_wsl = true);

std::string unix_to_windows_file_path(std::string file_path, bool is_wsl = true);

std::string windows_path_to_host_operating_system_path(std::string file_path, bool is_wsl = true);

FileSystemPathUtils.cpp

#include "FileSystemPathUtils.hpp"

#include <string>
#include <algorithm>
#include <sstream>
#include <utility>
#include <cstring>

std::string windows_to_unix_file_path(std::string file_path, bool is_wsl) {
    // Replace the slashes
    std::replace(file_path.begin(), file_path.end(), WINDOWS_FILE_PATH_SEPARATOR, UNIX_FILE_PATH_SEPARATOR);

    // Convert the drive letter to lowercase
    std::transform(file_path.begin(), file_path.begin() + 1, file_path.begin(),
                   [](unsigned char character) {
                       return std::tolower(character);
                   });

    // Remove the colon
    const auto drive_letter = file_path.substr(0, 1);
    const auto remaining_path = file_path.substr(2, file_path.size() - 2);
    file_path = drive_letter + remaining_path;

    std::stringstream stringstream;

    if (is_wsl) {
        stringstream << WSL_FILE_PATH_HEADER;
    }

    stringstream << "/";
    stringstream << file_path;

    return stringstream.str();
}

std::string unix_to_windows_file_path(std::string file_path, bool is_wsl) {
    if (is_wsl) {
        file_path = file_path.erase(0, strlen(WSL_FILE_PATH_HEADER));
    }

    // Delete the leading forward slash
    file_path.erase(0, 1);

    // Convert the drive letter to uppercase
    std::transform(file_path.begin(), file_path.begin() + 1, file_path.begin(),
                   [](unsigned char character) {
                       return std::toupper(character);
                   });

    // Replace the slashes
    std::replace(file_path.begin(), file_path.end(), UNIX_FILE_PATH_SEPARATOR,
                 WINDOWS_FILE_PATH_SEPARATOR);

    std::stringstream stringstream;
    stringstream << file_path.at(0);
    stringstream << ":";
    stringstream << file_path.substr(1, file_path.size() - 1);

    return stringstream.str();
}

std::string windows_path_to_host_operating_system_path(std::string file_path, bool is_wsl) {
#ifdef _WIN32
    return file_path;

#else
    return windows_to_unix_file_path(std::move(file_path), is_wsl);

#endif
}
于 2019-10-12T20:57:40.117 回答