Odczytanie folderu w któym znajduje się aplikacja niezależne od środowiska i platformy

0
#include <iostream>
using namespace std;

int main (int argc, char * argv[]) {
	cout << "the address is: " << argv [0] << endl;
	return 0;
}

W POWER SHELL ten kod zwraca pełną ścieżkę
w CMD i BASH kod zwraca ścieżkę jaka została użyta do uruchomienia

Potrzebuję ścieżkę do folderu w której jest uruchomiona aplikacja
Czy taka koncepcja jest słuszna ?

#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;
int main(int argc, char * argv[])
{
    // std::cout << "current_path = " << fs::current_path() << '\n'; 
    // std::cout << "argv[0] = " << argv[0]<< '\n'; 

    auto full_path = fs::current_path();
    full_path /= argv[0];   // jak argv[0] jest ablsolutne to nadpisze wartosc jak nie to doda 

    std::cout << "*** full_path_to_APP = " << full_path <<  '\n'; 
    std::cout << "*** full_path_to_DIR = "<< full_path.parent_path()  <<  '\n'; 

}
2
[pts/12:krzaq@krzaq:/tmp]% /home/krzaq/code/cpptest/wb
*** full_path_to_APP = "/home/krzaq/code/cpptest/wb"
*** full_path_to_DIR = "/home/krzaq/code/cpptest"
[pts/12:krzaq@krzaq:/tmp]% ../home/krzaq/code/cpptest/wb
*** full_path_to_APP = "/tmp/../home/krzaq/code/cpptest/wb"
*** full_path_to_DIR = "/tmp/../home/krzaq/code/cpptest"
[pts/12:krzaq@krzaq:/tmp]% PATH=/home/krzaq/code/cpptest:$PATH which wb
/home/krzaq/code/cpptest/wb
[pts/12:krzaq@krzaq:/tmp]% PATH=/home/krzaq/code/cpptest:$PATH wb
*** full_path_to_APP = "/tmp/wb"
*** full_path_to_DIR = "/tmp"

To jest ciekawe zachowanie shella.

1

Jeszcze bardziej komplikując:

/tmp $ cat runner.c 
#include <unistd.h>
int main() {
    char * const argv[] = {"byle śmieci", NULL};
    char * const envp[] = {NULL};
    execve("./wb", argv, envp);
}
/tmp $ cat wb.cc 
#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;
int main(int argc, char * argv[])
{
    // std::cout << "current_path = " << fs::current_path() << '\n'; 
    // std::cout << "argv[0] = " << argv[0]<< '\n'; 

    auto full_path = fs::current_path();
    full_path /= argv[0];   // jak argv[0] jest ablsolutne to nadpisze wartosc jak nie to doda 

    std::cout << "*** full_path_to_APP = " << full_path <<  '\n'; 
    std::cout << "*** full_path_to_DIR = "<< full_path.parent_path()  <<  '\n'; 

}
/tmp $ gcc runner.c -o runner
/tmp $ g++ wb.cc -o wb
/tmp $ ./runner 
*** full_path_to_APP = "/tmp/byle śmieci"
*** full_path_to_DIR = "/tmp"

0

W pascalu jakoś lepiej to rozwiązali :)

program wb;
uses
  SysUtils;
begin
  writeln('pascal FULL_PATH_APP =' , paramstr(0));
  writeln('pascal FULL_PATH_DIR =' , ExtractFilePath(paramstr(0)));
end.

Wszystkie przyklady @kq zwracaja tak samo:

pascal FULL_PATH_APP =/home/krzaq/code/cpptest/wb
pascal FULL_PATH_DIR =/home/krzaq/code/cpptest/

Przyklad @enedil
tez zwraca to samo

pascal FULL_PATH_APP =/home/krzaq/code/cpptest/wb
pascal FULL_PATH_DIR =/home/krzaq/code/cpptest/

Na Linux taka magia: odczyt z pliku /proc/self/exe do globalnej zmiennej "execpathstr" i potem zwraca to paramstr(0)

procedure SysInitExecPath;
var
  i    : longint;
begin
  execpathstr[0]:=#0;
  i:=Fpreadlink('/proc/self/exe',@execpathstr[1],high(execpathstr));
  { it must also be an absolute filename, linux 2.0 points to a memory
    location so this will skip that }
  if (i>0) and (execpathstr[1]='/') then
     execpathstr[0]:=char(i);
end; 

tutaj taki długi watek na temat problemu:
https://stackoverflow.com/questions/1023306/finding-current-executables-path-without-proc-self-exe

Rozwiązanie https://github.com/gpakosz/whereami

1 użytkowników online, w tym zalogowanych: 0, gości: 1