Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Need help with relative file path

Reply
Thread Tools

Need help with relative file path

 
 
Thomas Børlum
Guest
Posts: n/a
 
      06-21-2008
Hey all,

I'm writing a c++ program that needs to read a file. I'm trying to read
a file that is in the same directory as the executable.

Everything works fine if I execute the program while in the program's
directory. What I need to do is read that file regardless of where
(cwd) I execute the program from, without hardcoding the absolute since
the program might be moved or be in differant locations on other
computers.

What should I do?

PS. I'm using the boost filesystem framework if it helps.


 
Reply With Quote
 
 
 
 
Martin York
Guest
Posts: n/a
 
      06-21-2008
On Jun 21, 8:11*am, Thomas Børlum <(E-Mail Removed)> wrote:
> Hey all,
>
> I'm writing a c++ program that needs to read a file. I'm trying to read
> a file that is in the same directory as the executable.
>
> Everything works fine if I execute the program while in the program's
> directory. What I need to do is read that file regardless of where
> (cwd) I execute the program from, without hardcoding the absolute since
> the program might be moved or be in differant locations on other
> computers.
>
> What should I do?
>
> PS. I'm using the boost filesystem framework if it helps.


Most OS's will give you the command used to execute your program in
argv[0]
This will usually include the path

int main(int argc,char* argv[])
{
std::cout << argv[0] << "\n\n";
}

NB. It may be absolute or relative.
 
Reply With Quote
 
 
 
 
Juha Nieminen
Guest
Posts: n/a
 
      06-21-2008
Martin York wrote:
> Most OS's will give you the command used to execute your program in
> argv[0]
> This will usually include the path


Actually it's rather usual that argv[0] is simply what you wrote in
the command line as the program's name, without any additions.
 
Reply With Quote
 
Thomas Børlum
Guest
Posts: n/a
 
      06-21-2008
On 2008-06-21 17:50:33 +0200, Martin York <(E-Mail Removed)> said:

> On Jun 21, 8:11*am, Thomas Børlum <(E-Mail Removed)> wrote:
>> Hey all,
>>
>> I'm writing a c++ program that needs to read a file. I'm trying to read
>> a file that is in the same directory as the executable.
>>
>> Everything works fine if I execute the program while in the program's
>> directory. What I need to do is read that file regardless of where
>> (cwd) I execute the program from, without hardcoding the absolute since
>> the program might be moved or be in differant locations on other
>> computers.
>>
>> What should I do?
>>
>> PS. I'm using the boost filesystem framework if it helps.

>
> Most OS's will give you the command used to execute your program in
> argv[0]
> This will usually include the path
>
> int main(int argc,char* argv[])
> {
> std::cout << argv[0] << "\n\n";
> }
>
> NB. It may be absolute or relative.


Thanks that got me on the right track. I've done the following:

path program_path(string(argv[0]) + "/..");
program_path = complete(program_path);
string settings_file = program_path.string() + "/settings.txt";

works great.


 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      06-21-2008
On Jun 21, 5:50 pm, Martin York <(E-Mail Removed)> wrote:
> On Jun 21, 8:11 am, Thomas Børlum <(E-Mail Removed)> wrote:
> > I'm writing a c++ program that needs to read a file. I'm
> > trying to read a file that is in the same directory as the
> > executable.


> > Everything works fine if I execute the program while in the
> > program's directory. What I need to do is read that file
> > regardless of where (cwd) I execute the program from,
> > without hardcoding the absolute since the program might be
> > moved or be in differant locations on other computers.


> > What should I do?


> > PS. I'm using the boost filesystem framework if it helps.


> Most OS's will give you the command used to execute your
> program in argv[0] This will usually include the path


First, of course: I'm not sure what you mean by "most OS's", but
Unix certainly doesn't, and IIRC, nor does Windows. Unix, at
any rate, gives you whatever the invoking program decides.
(Note that this is NOT conform to the C or C++ standards;
strictly speaking, a conforming implementation of C or C++ is
impossible under Unix, and I'm pretty sure under Windows as
well.)

Secondly, of course, it's quite exceptional, both under Unix and
under Windows, for the invoking command to include the path.
In these two systems, the actual path is normally obtained from
an environment variable.

> int main(int argc,char* argv[])
> {
> std::cout << argv[0] << "\n\n";
> }


> NB. It may be absolute or relative.


Most of the time, it's relative from some arbitrary entry in the
PATH environment variable.

I've encountered this problem several times in the past; at
least under Unix, there is no possible solution from within the
program.

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      06-21-2008
On Jun 21, 6:21 pm, Juha Nieminen <(E-Mail Removed)> wrote:
> Martin York wrote:
> > Most OS's will give you the command used to execute your program in
> > argv[0]
> > This will usually include the path


> Actually it's rather usual that argv[0] is simply what you
> wrote in the command line as the program's name, without any
> additions.


That's more or less what the standard requires. Under Unix, of
course, this only works if the shell used to start the command
collaborates (most do). And it leaves open the question as to
what should be in argv[0] if the command is not started from the
command line, but from some other program.

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
Juha Nieminen
Guest
Posts: n/a
 
      06-26-2008
James Kanze wrote:
> On Jun 21, 6:21 pm, Juha Nieminen <(E-Mail Removed)> wrote:
>> Martin York wrote:
>>> Most OS's will give you the command used to execute your program in
>>> argv[0]
>>> This will usually include the path

>
>> Actually it's rather usual that argv[0] is simply what you
>> wrote in the command line as the program's name, without any
>> additions.

>
> That's more or less what the standard requires. Under Unix, of
> course, this only works if the shell used to start the command
> collaborates (most do). And it leaves open the question as to
> what should be in argv[0] if the command is not started from the
> command line, but from some other program.


Also, if I'm not mistaken, the C standard doesn't actually guarantee
that argv[0] will contain anything at all (although I don't remember if
that means that argv[0] could actually be a null pointer, or if it
simply means that it points to an empty string).

I assume the C++ standard inherits the same specification.
 
Reply With Quote
 
emarcari
Guest
Posts: n/a
 
      06-26-2008
On Jun 21, 12:11 pm, Thomas Børlum <(E-Mail Removed)> wrote:
> Hey all,
>
> I'm writing a c++ program that needs to read a file. I'm trying to read
> a file that is in the same directory as the executable.
>
> Everything works fine if I execute the program while in the program's
> directory. What I need to do is read that file regardless of where
> (cwd) I execute the program from, without hardcoding the absolute since
> the program might be moved or be in differant locations on other
> computers.
>
> What should I do?
>
> PS. I'm using the boost filesystem framework if it helps.


You may use getenv, doing something like this:
std::string source_dir = getenv( "srcdir" );

Look at http://www.cplusplus.com/reference/c...ib/getenv.html,
that there are another examples.
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      06-27-2008
On Jun 26, 11:58 am, Juha Nieminen <(E-Mail Removed)> wrote:
> James Kanze wrote:
> > On Jun 21, 6:21 pm, Juha Nieminen <(E-Mail Removed)> wrote:
> >> Martin York wrote:
> >>> Most OS's will give you the command used to execute your
> >>> program in argv[0] This will usually include the path


> >> Actually it's rather usual that argv[0] is simply what you
> >> wrote in the command line as the program's name, without any
> >> additions.


> > That's more or less what the standard requires. Under Unix, of
> > course, this only works if the shell used to start the command
> > collaborates (most do). And it leaves open the question as to
> > what should be in argv[0] if the command is not started from the
> > command line, but from some other program.


> Also, if I'm not mistaken, the C standard doesn't actually
> guarantee that argv[0] will contain anything at all (although
> I don't remember if that means that argv[0] could actually be
> a null pointer, or if it simply means that it points to an
> empty string).


> I assume the C++ standard inherits the same specification.


It does, more or less. First, argc may be 0, in which case,
argv[0] is guaranteed to be a null pointer (and accessing any
other argv is undefined behavior). If argc is greater than 0,
then "the string pointed to by argv[0] represents the program
name; argv[0][0] shall be the null character if the program name
is not available from the host environment." Note that this
does NOT say that the implementation may unconditionally place
an empty string in argv; it says that it may put an empty string
there IF "the program name is not available from the host
environment" (from the C standard), or ``argv[0] shall be the
pointer to the initial character of a NTMBS that represents the
name used to invoke the program or ""'' (from the C++ standard).

Note that the C standard does not define what it means by
"program name": is it the basename, the name as it appears in
the command line, or the full pathname? The C++ standard is
univocal: it must be the name as it appears in the command line.
On the other hand, the C standard requires the name, if it is
available; the C++ standard leaves it up to the implementation.
(The reason that I bring up the C standard here is that I
imagine most implementations will use common code for this,
whether main is in C or in C++, and so should be conform to both
standards.)

Of course, this requirement is ignored more often than it is
met; Unix doesn't make the program name available in any shape,
form or fashion, and I don't think Windows does either, so a
conforming C or C++ implementation must, strictly speaking,
always put an empty string in argv[0]. None do, at least that I
know of, and Posix has a conflicting requirement that argv[0]
actually contain a string specified by the program which starts
your program (which calls the system function execv). All of
the Unix shells I have handy under Solaris (sh, ksh and bash)
*do* pass the name from the command line as argv[0], when
starting a program, as does the default command interpreter
under Windows. The bash in CygWin doesn't, however, and of
course, if your program is started by some other tool, you're at
the mercy of that tool. (I have no idea, for example, what
you'll get if your program is started by clicking an icon on the
desktop. Hopefully, whatever is present in the "Target:" field
of the properties, but I have no way of verifying this.)

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      06-27-2008
On Jun 26, 2:13 pm, emarcari <(E-Mail Removed)> wrote:
> On Jun 21, 12:11 pm, Thomas Børlum <(E-Mail Removed)> wrote:
> > I'm writing a c++ program that needs to read a file. I'm
> > trying to read a file that is in the same directory as the
> > executable.


> > Everything works fine if I execute the program while in the
> > program's directory. What I need to do is read that file
> > regardless of where (cwd) I execute the program from,
> > without hardcoding the absolute since the program might be
> > moved or be in differant locations on other computers.


> > What should I do?


> > PS. I'm using the boost filesystem framework if it helps.


> You may use getenv, doing something like this:
> std::string source_dir = getenv( "srcdir" );


Don't ever write something like this. It will generally crash,
since getenv returns a null pointer if the specified variable
isn't set (and "srcdir" generally isn't).

With regards to obtaining the full pathname of the executable,
something like this depends on whoever starts the executable
setting the appropriate variable. Bash sets "_" to the full
path name, but I don't know of any other program which sets
anything, so unless you can guarantee that your program will
only be started by bash, you can't use this.

> Look at
> http://www.cplusplus.com/reference/c...ib/getenv.html,
> that there are another examples.


Which very clearly says that getenv may return a null pointer,
so it cannot be used as an initializer for a string.

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
FileUpload control doesn't work (fail in client side early stages) when path is relative i.e "\\path.." Oren ASP .Net 1 04-29-2007 04:20 PM
How do I convert an absolute path into a relative path Nigel Wilkinson Ruby 2 07-25-2005 07:37 PM
absolute path versus relative path in JSP Matt Java 3 07-08-2004 08:31 PM
relative file path Asad Java 7 05-28-2004 04:58 AM
Make a relative url path from an absolute path to another one Thomas Guettler Python 3 10-27-2003 04:41 PM



Advertisments