473,386 Members | 1,720 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Need help with relative file path

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.
Jun 27 '08 #1
12 8559
On Jun 21, 8:11*am, Thomas Børlum <bor...@gmail.comwrote:
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.
Jun 27 '08 #2
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.
Jun 27 '08 #3
On 2008-06-21 17:50:33 +0200, Martin York <Ma***************@gmail.comsaid:
On Jun 21, 8:11*am, Thomas Børlum <bor...@gmail.comwrote:
>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.
Jun 27 '08 #4
On Jun 21, 5:50 pm, Martin York <Martin.YorkAma...@gmail.comwrote:
On Jun 21, 8:11 am, Thomas Børlum <bor...@gmail.comwrote:
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:ja*********@gmail.com
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
Jun 27 '08 #5
On Jun 21, 6:21 pm, Juha Nieminen <nos...@thanks.invalidwrote:
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:ja*********@gmail.com
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
Jun 27 '08 #6
Thomas Børlum <bo****@gmail.comkirjutas:
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.
On Windows, getting the directory where the executable file is located is
easy (GetModuleFileName(NULL, ...)). On Linux/Unix it's much harder, for
starters the problem is not uniquely defined (you can have hardlinks to the
same inode in different directories). One can mimick it to some extent by
using argv[0], cwd() and which/PATH, but this requires collaboration by the
caller, as already mentioned by other responders.

Paavo
Jun 27 '08 #7
James Kanze wrote:
On Jun 21, 6:21 pm, Juha Nieminen <nos...@thanks.invalidwrote:
>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.
Jun 27 '08 #8
On Jun 21, 12:11 pm, Thomas Børlum <bor...@gmail.comwrote:
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.
Jun 27 '08 #9
"Alf P. Steinbach" <al***@start.nokirjutas:
* James Kanze:
[...]
>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,

Huh?
From Windows SDK documentation:

LPTSTR WINAPI GetCommandLine(void);

The return value is a pointer to the command-line string for the current
process.
....
Note The name of the executable in the command line that the operating
system provides to a process is not necessarily identical to that in the
command line that the calling process gives to the CreateProcess
function. The operating system may prepend a fully qualified path to an
executable name that is provided without a fully qualified path.

So it seems Windows makes it available in some shape or fashion ;-)

Regards
Paavo
Jun 27 '08 #10
On Jun 27, 7:15 pm, Paavo Helde <nob...@ebi.eewrote:
"Alf P. Steinbach" <al...@start.nokirjutas:
* James Kanze:
[...]
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,
Huh?
From Windows SDK documentation:
LPTSTR WINAPI GetCommandLine(void);
The return value is a pointer to the command-line string for
the current process.
And when the process wasn't started from a command line?
...
Note The name of the executable in the command line that the
operating system provides to a process is not necessarily
identical to that in the command line that the calling process
gives to the CreateProcess function. The operating system may
prepend a fully qualified path to an executable name that is
provided without a fully qualified path.
So it seems Windows makes it available in some shape or
fashion ;-)
I seem to recall experimenting at one time with Windows, and
seeing exactly the behavior I got from Unix. And if I
understand the documentation of CreateProcess correctly, if I
call it with something like:

CreateProcess( "C:\\Hidden\\even more hidden\\myProg.exe",
"C:\\Documents and Settings\\James Kanze\\...",
// all the rest of the verbage...
) ;

GetCommandLine is going to return the second string, which
doesn't begin to give the slightest hint about where the actual
executable is situated. (On the other hand, given the number of
functions in the Windows interface, it wouldn't surprise me if
there wasn't one to return the first argument to CreateProcess
as well. And from the documentation, that might be enough.)

In sum, it's exactly like the situation in Unix: if the invoking
program collaborates (and the various command interpreters
generally do), then it works, but everything depends on the
invoking program.

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Jun 27 '08 #11
James Kanze <ja*********@gmail.comwrote in news:c069673d-4ce6-401b-b340-
3a**********@y21g2000hsf.googlegroups.com:
>
GetCommandLine is going to return the second string, which
doesn't begin to give the slightest hint about where the actual
executable is situated. (On the other hand, given the number of
functions in the Windows interface, it wouldn't surprise me if
there wasn't one to return the first argument to CreateProcess
as well. And from the documentation, that might be enough.)
GetModuleName() with a NULL will give you the exe-s name, but this
digresses from the topic. :)

joe
Jun 27 '08 #12
James Kanze <ja*********@gmail.comkirjutas:
On Jun 27, 7:15 pm, Paavo Helde <nob...@ebi.eewrote:
>"Alf P. Steinbach" <al...@start.nokirjutas:
* James Kanze:
[...]
>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,
Huh?
>From Windows SDK documentation:
>LPTSTR WINAPI GetCommandLine(void);
>The return value is a pointer to the command-line string for
the current process.

And when the process wasn't started from a command line?
>...
Note The name of the executable in the command line that the
operating system provides to a process is not necessarily
identical to that in the command line that the calling process
gives to the CreateProcess function. The operating system may
prepend a fully qualified path to an executable name that is
provided without a fully qualified path.
>So it seems Windows makes it available in some shape or
fashion ;-)

I seem to recall experimenting at one time with Windows, and
seeing exactly the behavior I got from Unix. And if I
understand the documentation of CreateProcess correctly, if I
call it with something like:

CreateProcess( "C:\\Hidden\\even more hidden\\myProg.exe",
"C:\\Documents and Settings\\James Kanze\\...",
// all the rest of the verbage...
) ;

GetCommandLine is going to return the second string, which
doesn't begin to give the slightest hint about where the actual
executable is situated. (On the other hand, given the number of
functions in the Windows interface, it wouldn't surprise me if
there wasn't one to return the first argument to CreateProcess
as well. And from the documentation, that might be enough.)

In sum, it's exactly like the situation in Unix: if the invoking
program collaborates (and the various command interpreters
generally do), then it works, but everything depends on the
invoking program.
I read the documentation of Windows CreateProcess(), and it seems kind of
a serious hacking attempt. I cannot understand from the documentation if
the first and second argument are joined or not, and what is visible in
GetCommandLine(). But of course, this does not surprise me at least.

In any case, as GetModuleBaseName(...,NULL,...) gives the full path of
the executable file which was used for starting the process, one does not
have to worry too much about GetCommandLine().

Sorry about wandering off-topic!

Paavo
Jun 27 '08 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: GunFro | last post by:
Hi. I want php.ini in my own place, say /etc not default /usr/local/bin. So when I configure I use --with-config-file-path=/etc .... Easy !? It dose not work, well it configure, make and make...
7
by: middletree | last post by:
I usually use SQL Server, but have occasionally had to use Access. This is such an occasion. My research, mainly at aspfaq.com, has been that you need to put the file path in your connection...
2
by: Teis Draiby | last post by:
(Using C#) Question 1: Is there an easy build-in support for determining wether a given file path is 1) A valid file path (Only legal characters) 2) The file exists 3) The path exists
1
by: Alex VanderWoude | last post by:
I am trying to <include> some text into an XML documentation topic, but that text is stored in a file that is in a different directory than the "current" XML file. Using a relative path does not...
2
by: Harshdeep Mehta | last post by:
Hi all gurus, Myself Harshdeep Mehta, you can call me Harsh. I struck up in a situation where I need to define relative path in Web.Config. I.e. suppose I have a "Export" named folder, besides...
1
by: Peted | last post by:
Hello bellow is select sample of code im using to dynamicaly load assembley's and it works, but the assembley.loadfile requires that i use a absolute directory path. Is there anyway i can use...
1
by: Bambers | last post by:
hi there, i have created a vb.net compact framework program for a mobile pc. i now need to upload a text file produced by the program onto my server. the file always remains in the same...
1
by: BlouHond | last post by:
Hi, I'm using VB.net 2005. My dataset is called DsDetails1 My XML file is called details.xml When I use ReadXML, is there any way that I can set the path of this XML file to be read to be the...
3
by: Peter Wang | last post by:
Hi, all. I recently encountered a very annoying problem while using Zend Framework(ZF). We use ZF in our web application, and it works fine at the beginning, but later when concurrent...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.