Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / C++ Новый топик    Ответить
 MSVC + std::filesystem: разделители пути в стиле Linux  [new]
petrav
Member

Откуда:
Сообщений: 2861
Есть путь на диске, разделитель в нём неизвестен. Даже может быть и прямой и
обратный слеш в одном пути. Нужно сделать путь абсолютным, но слеш что бы
был — прямой слеш. Под Windows.

namespace fs = std::filesystem;
try
{
    fs::path p = fs::path("..") / "../.." / "AppData";
    auto aaa = fs::weakly_canonical(p);
    auto bbb = fs::absolute(p);
    p.clear();
}
catch (std::filesystem::filesystem_error const &err)
{
}

Но не выходит. Пути `aaa` и `bbb` хорошие выходят. Но слеши не правильные — обратные!

И как же это сделать? :)
4 фев 21, 21:55    [22275157]     Ответить | Цитировать Сообщить модератору
 Re: MSVC + std::filesystem: разделители пути в стиле Linux  [new]
mayton
Member

Откуда: loopback
Сообщений: 51017
А распечатай на экране aaa, bbb.
4 фев 21, 23:37    [22275185]     Ответить | Цитировать Сообщить модератору
 Re: MSVC + std::filesystem: разделители пути в стиле Linux  [new]
ъъъъъ
Member

Откуда:
Сообщений: 1966
petrav
И как же это сделать? :)

Средствами std::filesystem никак. Для Windows можно все слеши привести к одному, который предпочтителен для Windows, т.е. к обратному слэшу. В методе make_preferred() замена L'/' на L'\\' вообще захардкодена.

Просто замени руками:
using namespace std;
namespace fs = std::filesystem;

        fs::path p = fs::path("..") / "../.." / "XYZ";
        wstring sss = fs::absolute(p);

        wcout << sss << endl;
        replace(sss.begin(), sss.end(), L'\\', L'/');
        wcout << sss << endl;


К сообщению приложен файл. Размер - 1Kb
5 фев 21, 07:30    [22275252]     Ответить | Цитировать Сообщить модератору
 Re: MSVC + std::filesystem: разделители пути в стиле Linux  [new]
petrav
Member

Откуда:
Сообщений: 2861
ъъъъъ
petrav
И как же это сделать? :)

Средствами std::filesystem никак. Для Windows можно все слеши привести к одному, который предпочтителен для Windows, т.е. к обратному слэшу. В методе make_preferred() замена L'/' на L'\\' вообще захардкодена.

Спасибо.
5 фев 21, 11:55    [22275408]     Ответить | Цитировать Сообщить модератору
 Re: MSVC + std::filesystem: разделители пути в стиле Linux  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 52921

ъъъъъ
Для Windows можно все слеши привести к одному, который предпочтителен для Windows, т.е. к
обратному слэшу.

Вообще-то Windows уже довольно давно всё равно, она работает с обеими слэшами без проблем.

Posted via ActualForum NNTP Server 1.5

5 фев 21, 14:04    [22275587]     Ответить | Цитировать Сообщить модератору
 Re: MSVC + std::filesystem: разделители пути в стиле Linux  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 7650
Dimitry Sibiryakov

ъъъъъ
Для Windows можно все слеши привести к одному, который предпочтителен для Windows, т.е. к
обратному слэшу.

Вообще-то Windows уже довольно давно всё равно, она работает с обеими слэшами без проблем.
+1 AFAIK
5 фев 21, 14:07    [22275590]     Ответить | Цитировать Сообщить модератору
 Re: MSVC + std::filesystem: разделители пути в стиле Linux  [new]
petrav
Member

Откуда:
Сообщений: 2861
Dimitry Sibiryakov

ъъъъъ
Для Windows можно все слеши привести к одному, который предпочтителен для Windows, т.е. к
обратному слэшу.

Вообще-то Windows уже довольно давно всё равно, она работает с обеими слэшами без проблем.

Насколько я помню по чтению документации осталось несколько функций из WinAPI, которые не воспринимают прямые слеши. Плюс я наблюдаю, что WSH не всегда понимает прямой слеш.

Но дело не в этом, дело в негибкости std::filesystem. Так что пришлось применить std::replace.
5 фев 21, 14:22    [22275610]     Ответить | Цитировать Сообщить модератору
 Re: MSVC + std::filesystem: разделители пути в стиле Linux  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 52921

petrav
Плюс я наблюдаю, что WSH не всегда понимает прямой слеш.

Так мы же в Си разделе, что нам до какого-то скрипта?..

Posted via ActualForum NNTP Server 1.5

5 фев 21, 14:32    [22275619]     Ответить | Цитировать Сообщить модератору
 Re: MSVC + std::filesystem: разделители пути в стиле Linux  [new]
petrav
Member

Откуда:
Сообщений: 2861
Dimitry Sibiryakov

petrav
Плюс я наблюдаю, что WSH не всегда понимает прямой слеш.

Так мы же в Си разделе, что нам до какого-то скрипта?..

К слову пришлось. Это же встроенный в Винду компонент, хоть и устаревший. Это часть Винды. Да и вызывает же он WinAPI.
5 фев 21, 15:22    [22275680]     Ответить | Цитировать Сообщить модератору
 Re: MSVC + std::filesystem: разделители пути в стиле Linux  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 52921

Между "понимает" в предыдущем сообщении и "вызывает" в этом - толстая-толстая прослойка
дикого кода.

Posted via ActualForum NNTP Server 1.5

5 фев 21, 15:39    [22275704]     Ответить | Цитировать Сообщить модератору
 Re: MSVC + std::filesystem: разделители пути в стиле Linux  [new]
ъъъъъ
Member

Откуда:
Сообщений: 1966
Dimitry Sibiryakov
ъъъъъ
Для Windows можно все слеши привести к одному, который предпочтителен для Windows, т.е. к
обратному слэшу.

Вообще-то Windows уже довольно давно всё равно, она работает с обеими слэшами без проблем.

Я лишь сказал о логике, реализованной в std:: filesystem.
5 фев 21, 16:21    [22275753]     Ответить | Цитировать Сообщить модератору
 Re: MSVC + std::filesystem: разделители пути в стиле Linux  [new]
mayton
Member

Откуда: loopback
Сообщений: 51017
Вот тут достаточно хорошо описаны различия

https://en.wikipedia.org/wiki/Path_(computing)
5 фев 21, 20:14    [22275996]     Ответить | Цитировать Сообщить модератору
 Re: MSVC + std::filesystem: разделители пути в стиле Linux  [new]
ъъъъъ
Member

Откуда:
Сообщений: 1966
mayton,

при чем тут вики и реализация Windows. ТС хочет средствами std::filesystem управлять значением разделителя директорий в строке пути. Сие - невозможно, ибо классе path член preferres_separator является константным, и определен как бэкслэш для Windows, и как форвардслэш для POSIX. Сие описано "в стандарте". В конкретной реализации (MS VS - 2019) - ещё суровее, например, в make_preferred() не используется даже не preferres_separator, а бессовестно
            _STD replace(_Text.begin(), _Text.end(), L'/', L'\\');
5 фев 21, 22:09    [22276037]     Ответить | Цитировать Сообщить модератору
 Re: MSVC + std::filesystem: разделители пути в стиле Linux  [new]
petrav
Member

Откуда:
Сообщений: 2861
ъъъъъ
mayton,

при чем тут вики и реализация Windows. ТС хочет средствами std::filesystem управлять значением разделителя директорий в строке пути. Сие - невозможно, ибо классе path член preferres_separator является константным, и определен как бэкслэш для Windows, и как форвардслэш для POSIX. Сие описано "в стандарте". В конкретной реализации (MS VS - 2019) - ещё суровее, например, в make_preferred() не используется даже не preferres_separator, а бессовестно
            _STD replace(_Text.begin(), _Text.end(), L'/', L'\\');

Я, конечно, видел что preferred_separator константный. Просто перед написанием очередного
костыля решил уточнить: а вдруг я что-то не дочитал. :)

Сообщение было отредактировано: 5 фев 21, 22:29
5 фев 21, 22:35    [22276051]     Ответить | Цитировать Сообщить модератору
 Re: MSVC + std::filesystem: разделители пути в стиле Linux  [new]
mayton
Member

Откуда: loopback
Сообщений: 51017
ъъъъъ
mayton,

при чем тут вики и реализация Windows. ТС хочет средствами std::filesystem управлять значением разделителя директорий в строке пути. Сие - невозможно, ибо классе path член preferres_separator является константным, и определен как бэкслэш для Windows, и как форвардслэш для POSIX. Сие описано "в стандарте". В конкретной реализации (MS VS - 2019) - ещё суровее, например, в make_preferred() не используется даже не preferres_separator, а бессовестно
            _STD replace(_Text.begin(), _Text.end(), L'/', L'\\');

Потому-что тема топика - Windows. А там - самые хитрые правила работы с Path.
5 фев 21, 22:54    [22276057]     Ответить | Цитировать Сообщить модератору
 Re: MSVC + std::filesystem: разделители пути в стиле Linux  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 52921

ъъъъъ
классе path член preferres_separator является *константным*

Но у его конструкторов есть второй параметр. О котором аффтар и не дочитал.

Posted via ActualForum NNTP Server 1.5

5 фев 21, 23:08    [22276061]     Ответить | Цитировать Сообщить модератору
 Re: MSVC + std::filesystem: разделители пути в стиле Linux  [new]
petrav
Member

Откуда:
Сообщений: 2861
Dimitry Sibiryakov

ъъъъъ
классе path член preferres_separator является *константным*

Но у его конструкторов есть второй параметр. О котором аффтар и не дочитал.

Читал, оно не помогает.
5 фев 21, 23:12    [22276063]     Ответить | Цитировать Сообщить модератору
 Re: MSVC + std::filesystem: разделители пути в стиле Linux  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 7650
petrav
Dimitry Sibiryakov

пропущено...

Но у его конструкторов есть второй параметр. О котором аффтар и не дочитал.

Читал, оно не помогает.

По справедливости говоря, вы не дали ошибку.
Вы только сказали что "не в ту сторону" для вас визуально.
Вот например, в Qt слеши визуально это внутреннее представление пути. Хоть вертикальные черточки с:|темп.
Кроссплатформенность обязывает.
5 фев 21, 23:53    [22276081]     Ответить | Цитировать Сообщить модератору
 Re: MSVC + std::filesystem: разделители пути в стиле Linux  [new]
petrav
Member

Откуда:
Сообщений: 2861
Метод std::filesystem::path::generic_string() возвращает строку с разделителями в стиле Линукс.

path = path.generic_string() + '/';

Странно что не работает второй аргумент конструктора std::filesystem::path.
6 фев 21, 09:20    [22276164]     Ответить | Цитировать Сообщить модератору
 Re: MSVC + std::filesystem: разделители пути в стиле Linux  [new]
petrav
Member

Откуда:
Сообщений: 2861
Всё с обратными слешами не смотря на fs::path::format::generic_format.

    namespace fs = std::filesystem;
    try
    {
        fs::path p = fs::path("..", fs::path::format::generic_format) / "../.." / "AppData";
        auto aaa = fs::weakly_canonical(p);
        auto bbb = fs::absolute(p);
        p.clear();
    }
    catch (std::filesystem::filesystem_error const &err)
    {
    }
6 фев 21, 09:33    [22276166]     Ответить | Цитировать Сообщить модератору
 Re: MSVC + std::filesystem: разделители пути в стиле Linux  [new]
Alex_Ustinov
Member

Откуда: Nickel
Сообщений: 3722
generic_format (since C++17)?
6 фев 21, 15:38    [22276351]     Ответить | Цитировать Сообщить модератору
Все форумы / C++ Ответить