Узнать полный путь к файлу
Пытаюсь написать свою реализацию ls, и столкнулся с такой проблемой: если я открываю папку, в которой лежит исполняемый файл, все работает хороошо, но ровно до того момента, пока я не открываю любую другую папку. Имя файлов считывается хорошо, но вот права доступа, к-ство ссылок, размер и дата модификации остаются идентичными(все для флага -l). Мне подсказали, что нужно модифицировать аргумент, добавив туда остальной путь от корневой папки, но это не работает, когда задаю вручную. Что нужно сделать, чтобы адекватно отобразить?
Отслеживать
задан 20 июн 2019 в 15:23
53 5 5 бронзовых знаков
сначала исходник, потом стулья.
20 июн 2019 в 16:54
В списке «разрешённых» функций отсутствуют необходимые для корректной работы программы, передайте «привет» преподавателю!
21 июн 2019 в 6:32
@0andriy как раз все, что нужно, тут указано. и что же по вашему мнению тут не хватает?
C++ как получить путь запущенного приложения?
использую c++17 c++20
имеется приложение, которое использует ресурсы используя относительные пути — как выяснить реальный путь в файловой системе до самого бинаря внутри кода?
апд
в общем найдено несколько способов:
1. только для систем с procfs — C++ как получить путь запущенного приложения? (комментарий)
2. по идее кроссплатформенный через sdl2 — C++ как получить путь запущенного приложения? (комментарий)
3. использовать метод нахождения используемый в which (определять является ли argv путем, если да то каким — относительным или абсолютным, если нет, то искать название бинарника по путям в env var PATH)
safocl ★★
15.01.21 01:50:13 MSK
← 1 2 3 →
я так понимаю std::filesystem не содержит такой возможности?
надо будет по подобию which делать ?
safocl ★★
( 15.01.21 02:24:46 MSK ) автор топика
Относительные относительно бинаря или таки рабочего каталога?
readlink(«/proc/self/exe», buf, bufsize)
anonymous
( 15.01.21 02:24:53 MSK )
Ответ на: комментарий от anonymous 15.01.21 02:24:53 MSK
относительные именно бинаря. — я просто юзаю файлы ресурсов — скажем бинарь может быть в /usr/bin, а ресы в /usr/share — неплоха было бы просто сделать ../share
но файл может же запускаться и просто по имени — тогда такой фокус не проходит по arcv[0].
safocl ★★
( 15.01.21 02:32:54 MSK ) автор топика
Ответ на: комментарий от anonymous 15.01.21 02:24:53 MSK
но походу да — для линукса тут будет именно readlink.
попробую в коде отвечу то или нет.
safocl ★★
( 15.01.21 02:38:53 MSK ) автор топика
Ответ на: комментарий от safocl 15.01.21 02:32:54 MSK
Если ты пишешь опенсорс и собрался складывать своё файло в /usr/bin и /usr/share, то эти пути, afaik, принято конфигурировать перед компиляцией. https://stackoverflow.com/questions/3239343/make-install-but-not-to-default-directories
anonymous
( 15.01.21 02:46:33 MSK )
Ответ на: комментарий от safocl 15.01.21 02:38:53 MSK
Это linux-специфично и непереносимо. Правильно сказали — конфигурировать пути при cборке.
slovazap ★★★★★
( 15.01.21 03:03:04 MSK )
Ответ на: комментарий от slovazap 15.01.21 03:03:04 MSK
https://en.cppreference.com/w/cpp/filesystem/read_symlink — я попробую вот енту функцию юзать — она вроде как тот сишный от unistd.h насколько я понимаю работает?
safocl ★★
( 15.01.21 03:04:57 MSK ) автор топика
Ответ на: комментарий от safocl 15.01.21 03:04:57 MSK
fs::read_symlink("/proc/self/exe")
работает именно так как я хотел
думаю можно закрывать.
для винды аналог как я понимаю енто GetModuleFileName?
safocl ★★
( 15.01.21 03:22:15 MSK ) автор топика
Ответ на: комментарий от safocl 15.01.21 03:04:57 MSK
Я не про readlink , а про /proc/self/exe — нигде кроме линукса её нет.
slovazap ★★★★★
( 15.01.21 03:35:01 MSK )
Ответ на: комментарий от slovazap 15.01.21 03:35:01 MSK
да понятно — ну в винде своя функция есть — через дефайны буду делать.
safocl ★★
( 15.01.21 03:50:42 MSK ) автор топика
Ответ на: комментарий от safocl 15.01.21 03:50:42 MSK
Кроме винды и линукса есть ещё куча операционных систем.
slovazap ★★★★★
( 15.01.21 04:14:35 MSK )
Ответ на: комментарий от slovazap 15.01.21 03:03:04 MSK

Правильно сказали — конфигурировать пути при cборке.
Это ещё хуже. Бинарник и данные должны работать из любого места.
X512 ★★★★★
( 15.01.21 04:24:49 MSK )
Ответ на: комментарий от slovazap 15.01.21 04:14:35 MSK

Кроме винды и линукса есть ещё куча операционных систем.
Ещё один #elif __OSNAME__ дописать. Можно ещё через argv[0] путь получить, но там могут быть символьные ссылки и относительные пути.
X512 ★★★★★
( 15.01.21 04:29:01 MSK )
Ответ на: комментарий от X512 15.01.21 04:29:01 MSK
в argv[0] еще может быть ваще другое — енто же не путь запускного файла — енто команда запуска — она может состоять из вообще других слов, нежели путь к exe.
в ентом то и проблема — пока я не начал устанавливать прогу в /usr/bin все было норм — но когда поставил туда и запустил не путем а командой — тоесть просто по названию проги — перестали действовать относительные пути к ресурсам.
я просто изначально думал чо в std::filesystem реализован механизм обнаружения пути к exe — но увы — нет.
safocl ★★
( 15.01.21 05:04:06 MSK ) автор топика
Последнее исправление: safocl 15.01.21 05:07:13 MSK (всего исправлений: 2)
Ответ на: комментарий от X512 15.01.21 04:24:49 MSK
потому что данные программа должна собирать с приоритетами:
- переменная среды MY_PROG_DATA
- через сборку препроцессора, $MY_PROG_DATA
- глобальное хостовые пути xdg
- пользовательские пути xdg
anonymous
( 15.01.21 06:06:07 MSK )
Ответ на: комментарий от anonymous 15.01.21 06:06:07 MSK

3 и 4 местами поменяй.
Siborgium ★★★★★
( 15.01.21 09:54:21 MSK )

Хрена вы норкоманы.
int main(int argc, char* argv[])
pon4ik ★★★★★
( 15.01.21 11:41:13 MSK )
Ответ на: комментарий от anonymous 15.01.21 06:06:07 MSK

Но в целом, глобальную проблему ТС решает именно такой подход, только и правда последние два пункта надо свапнуть.
pon4ik ★★★★★
( 15.01.21 11:48:57 MSK )
Резолвить argv[0] до абсолютного пути не помогает, если программа не была запущена по абсолютному пути:
$ cat ~/vcs/scripts/argv0.c #include int main(int argc, char ** argv) < puts(argv[0]); return 0; >$ make ~/vcs/scripts/argv0 cc argv0.c -o argv0 $ which argv0 /home/me/vcs/scripts/argv0 $ argv0 argv0
(Не говоря уже о том, что в системном вызове execve в argv[0] можно подставить любую чушь, не имеющую ничего общего с путём к исполняемому файлу.)
anonymous
( 15.01.21 11:52:27 MSK )
Ответ на: комментарий от anonymous 15.01.21 11:52:27 MSK

Лол, значит я был не прав, интересный факт, спасибки.
pon4ik ★★★★★
( 15.01.21 11:54:41 MSK )
Ответ на: комментарий от pon4ik 15.01.21 11:41:13 MSK

Надо ещё символьные ссылки резолвить.
X512 ★★★★★
( 15.01.21 11:55:57 MSK )
Ответ на: комментарий от safocl 15.01.21 02:32:54 MSK
а ресы в /usr/share — неплоха было бы просто сделать ../share
Так делать глупо.
После старта бинарники:
- Он считывает переменные окружения PATH_БЛАБЛА_ДЛЯ_БЛА и т.п. Если их нет, то использует дефолт (man hier).
- Использует параметры, если их нет, то использует дефолты (man hier).
- Он читает конфиг, где определены пути. Если его нет, то использует дефолт (man hier).
- Он использует стандартные пути (man hier).
Полные пути рулят.
anonymous
( 15.01.21 12:16:07 MSK )
Ответ на: комментарий от safocl 15.01.21 05:04:06 MSK

Файловая система и твой ехе это как бы разные вещи, с чего бы рантайм лабуде быть в std::filesystem?
seiken ★★★★★
( 15.01.21 12:52:58 MSK )
Ответ на: комментарий от anonymous 15.01.21 06:06:07 MSK
safocl ★★
( 15.01.21 13:33:25 MSK ) автор топика
Ответ на: комментарий от pon4ik 15.01.21 11:41:13 MSK
чуть выше уже был коммент на счет argv[0] — енто не путь исполняемого файла — а команда запуска программы — она может быть ваще не путем, да и ваще не особо относиться к названию бинаря проги.
safocl ★★
( 15.01.21 13:35:42 MSK ) автор топика
Ответ на: комментарий от anonymous 15.01.21 12:16:07 MSK
ну в таком случае если ты портабельно собрал прогу она не найдет ресы.
safocl ★★
( 15.01.21 13:37:22 MSK ) автор топика
Ответ на: комментарий от seiken 15.01.21 12:52:58 MSK
путь там указывается.
да и текущий каталог ведь можно узнать через std::filesystem — енто тоже рантайм сущность.
safocl ★★
( 15.01.21 13:38:51 MSK ) автор топика
кстати нашел один кроссплатформенный способ — через SDL2/SDL_filesystem.h — функция SDL_GetBasePath() возвращает реальный путь нахождения проги.
safocl ★★
( 15.01.21 13:40:46 MSK ) автор топика
Последнее исправление: safocl 15.01.21 13:47:26 MSK (всего исправлений: 1)
Ответ на: комментарий от anonymous 15.01.21 02:24:53 MSK

argv[0] ёпта, при старте приложения.
deep-purple ★★★★★
( 15.01.21 13:41:20 MSK )
Ответ на: комментарий от safocl 15.01.21 13:37:22 MSK
Разговор же идёт про обычный вариант сборки (/usr/bin, /usr/share и т.п.). С портабельной версией придётся работать через переменные окружения или ./бла-бла. Тут даже спорить не нужно.
anonymous
( 15.01.21 13:49:05 MSK )
Ответ на: комментарий от slovazap 15.01.21 03:03:04 MSK
Это linux-специфично и непереносимо.
Можно натравить which или своровать код поиска (по списку путей в PATH).
anonymous
( 15.01.21 13:50:03 MSK )
Ответ на: комментарий от anonymous 15.01.21 13:50:03 MSK
да зачем если есть /proc/self/exe симлинк ведущий к бинарю?
safocl ★★
( 15.01.21 13:53:02 MSK ) автор топика
Ответ на: комментарий от safocl 15.01.21 13:53:02 MSK
Это linux-специфично и непереносимо.
Это если надо переносимо. Решение, естественно, неточное — нужно чтобы совпали алгоритмы и данные для поиска пути у приложения и у системы.
anonymous
( 15.01.21 13:59:37 MSK )
Ответ на: комментарий от X512 15.01.21 04:24:49 MSK
Это ещё хуже. Бинарник и данные должны работать из любого места.
- Кто это сказал?
- Какие аргументы?
- В каких пределах это должно работать?
Потому что либо ты хардкодишь абсолютный путь, либо относительный. В первом случае ты можешь бинарник переносить куда угодно и он продолжит работать. Во втором можешь переносить только параллельно с данными. В разных случаях может потребоваться разное.
Претензия здесь не к одному из этих вариантов, потому что требование ровно одно — бинарник должен работать так как его установили, и ему удовлетворяют оба. Но к способу получения пути к бинарнику который непереносим, и быдлокод с /proc/self/exe просто сломается на *bsd, haiku, macos и ещё куче систем.
slovazap ★★★★★
( 15.01.21 14:53:10 MSK )
Ответ на: комментарий от slovazap 15.01.21 14:53:10 MSK
Но к способу получения пути к бинарнику который непереносим, и быдлокод с /proc/self/exe просто сломается на *bsd, haiku, macos и ещё куче систем.
ессесна — надо делать разные пути для проверки — сам способ не меняется на юникс подобных системах. — но выше же и сказано чо енто непереносимо.
safocl ★★
( 15.01.21 14:55:53 MSK ) автор топика
Ответ на: комментарий от X512 15.01.21 04:29:01 MSK
Ещё один #elif OSNAME дописать.
Это говённый код который надо допиливать под каждую новую систему чтобы запустить. Едва ли от автора можно ожидать что он знает как получить путь к бинарнику на всех существующих системах. И потом всё уткнётся в систему где этого сделать вообще нельзя и всё равно будет добавлен универсальный способ с абсолютным путём.
В итоге получаем:
- Коллекцию способов получить путь к бинарнику на несколько страниц мёртвого кода, из которого тестируется только тот что работает на системе автора
- Теряем поддержку относительной переносимости, потому что она уже не везде работает
Поэтому собственно везде и всегда используются абсолютные пути, и это единственный правильный способ.
Можно ещё через argv[0] путь получить, но там могут быть символьные ссылки и относительные пути.
Нельзя, если бинарник запущен через $PATH там вообще пути не будет. Поведение зависит от шелла и на самом деле там вообще не обязано оказаться что-либо осмысленное.
slovazap ★★★★★
( 15.01.21 15:08:17 MSK )
Ответ на: комментарий от slovazap 15.01.21 15:08:17 MSK
так а способ с применением sdl2 который я выше привел он что не везде работает где есть sdl2?
safocl ★★
( 15.01.21 15:10:12 MSK ) автор топика
Ответ на: комментарий от safocl 15.01.21 14:55:53 MSK
Какие ещё разные пути? На других системах нет никаких путей аналогичных /proc/self/exe
Как узнать и скопировать полный путь к файлу в Windows 10

Иногда в командной строке или при создании .BAT файла требуется указать полный путь к файлу. Некоторые начинающие пользователи не знают, как узнать полный путь к файлу, другие начинают его старательно набирать вручную, несмотря на нахождение этого файла не в самом удобном расположении. Есть способ проще — вы можете в два клика скопировать полный путь к файлу и вставить его.
В этой крайне короткой инструкции о том, как узнать и скопировать полный путь к файлу или папке в Windows 10, способ подойдет и для предыдущих версий системы.
- Как узнать полный путь к файлу или папке
- Как скопировать путь к файлу в буфер обмена
- Видео инструкция
Как узнать путь к файлу или папке
Если вам требуется узнать путь к файлу или папке в Windows, используя только встроенные средства системы, достаточно перейти в нужную папку, посмотреть путь к ней в адресной строке проводника и добавить к нему имя файла после знака «\». Также вы можете открыть свойства файла (нажав правой кнопкой мыши по нему и выбрав нужный пункт) и увидеть там путь к нему в поле «Расположение».

К этому расположению (которое можно скопировать из окна свойств) также добавляем \ и имя файла, которое также отображается в свойствах — получаем полный путь к файлу, например, для скриншота выше путь буде выглядеть как C:\Windows\Winhlp32.exe. Но это не обязательно делать вручную, есть способ проще.
Копирование пути к файлу или папке
В сторонних файловых менеджерах есть свои функции для выполнения рассматриваемой задачи, но вы можете легко скопировать путь к файлу и во встроенном проводнике Windows 10:

- Найдите нужный файл в проводнике.
- Удерживая Shift, нажмите правой кнопкой по этому файлу.
- Выберите пункт контекстного меню «Копировать как путь».
Готово — теперь вы можете вставить (Ctrl+V, Shift+Insert или через контекстное меню) в любое место, например, в командную строку. Путь к файлу вставляется в кавычках — для большинства применений удалять их не обязательно.
Копирование пути к папке еще проще: находясь в нужной папке, нажмите указателем мыши в правой части адресной строки проводника — весь путь будет выделен.

Скопируйте его в буфер обмена — Ctrl+C, Ctrl+Insert или с использованием контекстного меню.
Видео инструкция
Надеюсь, несмотря на краткость, материал окажется полезным для кого-то из читателей.
А вдруг и это будет интересно:
- Лучшие бесплатные программы для Windows
- TakeOwnershipEx — получение полного доступа к папкам и файлам и восстановление прав по умолчанию
- Ошибка 0x8007000d в Windows 11 или 10 — как исправить?
- Chrome открывает поиск вместо сайта — решение
- Недопустимая конфигурация приложения в Steam — варианты решения
- Ошибка при запуске приложения 0xc0000006 — как исправить?
- Windows 11
- Windows 10
- Android
- Загрузочная флешка
- Лечение вирусов
- Восстановление данных
- Установка с флешки
- Настройка роутера
- Всё про Windows
- В контакте
- Одноклассники
-
Дмитрий 10.05.2020 в 11:03
Получить полный путь к файлу созданного через ofstream
Файл: Получить полный путь к файлу и записать этот путь в отдельную переменную.
Доброго времени суток.Столкнулся с проблемой в ходе выполнения задачи. Мне нужно получить полный.

Получить полный путь к файлу
Как мне получить полный путь к файлу "1.bat", который находится в той же папке что и exe-ник.
Получить Полный путь к файлу по Дескриптору
Нашел вот этот пример, а как использовать не знаю. Подскажите Пожалуйста. static extern void.
Как получить полный путь к файлу?
Всем здравия и благополучия! Помогите пожлуйста разобраться с jquery которая была применина к.
Любитель чаепитий
3741 / 1798 / 565
Регистрация: 24.08.2014
Сообщений: 6,016
Записей в блоге: 1
Сообщение от Некий_Чел 
Чем это можно сделать?
Добавлено через 4 минуты
1 2 3 4 5 6 7 8 9 10 11
#include #include #include int main() { namespace fs = std::experimental::filesystem; const std::string filename = "file.txt"; std::ofstream file(filename); std::cout (fs::current_path().string() + "/" + filename) "\n"; }
Форумчанин
![]()
![]()
8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
Добавлено через 3 минуты
Сообщение от GbaLog- 
Для конкатенации лучше использовать специальные средства
http://en.cppreference.com/w/c. ath/append
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
GbaLog-, А так не проще?
1 2 3 4 5 6 7 8
#include #include int main() { std::string full_path = std::experimental::filesystem::canonical("aaa.txt").generic_string(); std::cout full_path std::endl; }
Форумчанин
![]()
![]()
8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
Тогда уж лучше абсолютный путь
1 2 3 4 5 6 7
#include #include int main() { std::cout std::experimental::filesystem::absolute("main.cpp") std::endl; }
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь

Получить полный путь к файлу из диалога открытия файла из js
Нужно кроссбраузерное решение. Сам файл мне не нужен, нужен только полный путь к нему. Запуск.
Макрос в OpenOffice Calc, как получить полный путь к файлу?
Здравствуйте! Делаю макрос в OO Calc , вывожу полный путь к файлу MsgBox ThisComponent.Location.

Как получить ПОЛНЫЙ ПУТЬ к файлу из сохраненной на листе гиперссылки?
Добрый день. У меня есть книга эксель, в которой на отдельном листе собраны гиперссылки на другие.

Узнать полный путь к файлу, через перетаскивание на форму?
Что-то я не пойму ни как. Как узнать полный путь к файлу, который перетащил на форму. По идее.