问题
I have a C++ project with a folder structure something like so:
root/trunk
root/trunk/src/...
root/trunk/include/...
root/trunk/utils/... <-- this has the `main` programs which are compiled
root/trunk/bin/... compiled binaries
root/data/... data used in the programs
In my source files, I sometimes refer to files included in the data subfolders. I want the paths I use to be relative paths (because I am sharing this project with someone else).
How can I ensure that the data files can always be found? Currently I use paths such as the following:
std::string my_data("../../../data/path/to/file.txt");
However, I find it difficult using this to work out where the relative path leads to, and can be messy when source files are moved. Is the a better way of accomplishing the same thing?
回答1:
A common method of organizing data files is to establish a "data root" folder at program startup, and then code your paths relative to that. The data root can be automatically determined by searching (the current directory and perhaps its parent, grandparent, etc, up to the real root.) for a specially named file or directory (eg ".foo"), and overridden by an environment variable or command-line switch (eg FOO_DATA_DIR="/home/fred/bar").
For conveniance the program could change its current working directory to the data root, or alternatively you can resolve your data root relative paths programmatically in userland.
回答2:
You should not make any assumptions about what the current working directory will be when your program is run - use a more robust method to determine the location of your data files, which doesn't rely on the working directory being set to anything in particular. Test this by setting the working directory to somewhere unrelated to your program and then run it from there, e.g.
$ cd /tmp
$ /path/to/my/program/root/trunk/bin/my_program
and see if it runs OK.
回答3:
Before going any further, you want to define a delivery directory
structure; what other users will see when they install your code. Then,
work from that: under Windows, you can use the function
GetModuleFileName
to find where your binary is located, and work from
that; under Unix, it's traditional to require the user to set an
environment variable, something like MYPROJ_ROOT
, and use that as the
root of your tree. Either way, you have a starting point; you want your
filenames relative to that, and not to the current working directory.
You can do this either by changing the current working directory for
your process (SetCurrentDirectory
under Windows, chdir
under Unix),
or (my preferred solution) by using something like boost::filesystem
to build up absolute names from the name of the root.
回答4:
There isn't quite enough code in your question to see exactly what you're doing, but in the past, I've used the __FILE__
preprocessor macro (and subsequently removed filenames/directories) to reference files which are relative to where source files are located:
http://www.codeguru.com/forum/showthread.php?t=380822
来源:https://stackoverflow.com/questions/9068081/refer-to-data-files-from-within-c-project