Question

I am writing a program in c++ that accepts a filename as an argument on the command line:

>> ./myprogram ../path/to/file.txt

I know I can simply open an fstream using argv[1], but the program needs more information about the exact location (ie. full pathname) of the file.

I thought about appending argv[1] to getcwd(), however obviously in the example above you'd end up with /path/../path/to/file.txt. Not sure whether fstream would resolve that path automatically, but even if it did, I still don't have the full path without a lot of string processing.

Of course, that method wouldn't work at all if the path provided was already absolute. And since this program may be run on Linux/Windows/etc, simply detecting a starting '/' character won't work to determine whether the argument was a full path or not.

I would think this is a fairly common issue to deal with path names across multiple OSs. So how does one retreive the full path name of a command line argument and how is this handled between operating systems?

Was it helpful?

Solution

Pathname handling is highly OS-specific: some OS have a hierarchy with just one root (e.g. / on Unix ), some have several roots a la MS-DOS' drive letters; some may have symbolic links, hard links or other kinds of links, which can make traversal tricky. Some may not even have the concept of a "canonical" path to a file (e.g. if a file has hard links, it has multiple names, none of which is more "canonical").

If you've ever tried to do path-name manipulation across multiple OS in Java, you know what I mean :-).

In short, pathname handling is system-specific, so you'll have to do it separately for each OS (family), or use a suitable library.

Edit:

You could look at Apache Portable Runtime, or at Boost (C++ though), both have pathname handling functions.

OTHER TIPS

...you'd end up with /path/../path/to/file.txt. Not sure whether fstream would resolve that path automatically, but even if it did, I still don't have the full path without a lot of string processing.

It does, and you can use /path/../path/ for everything you want without problems.

Anyway there is no standard function in C++ to do what you want. You would have to do it manually, and it wouldn't be trivial.. I suggest you keep the path as it is, it shouldn't cause any problems.

It is OS-dependent. If you are using linux you can look at realpath(). No doubt Windows has something comparable.

AFAIK there is no standard way.

however you could try this approach (written in pseudocode):

string raw_dirname=get_directory_part(argv[1])
string basename=get_filename_part(argv[1])
string cwd=getcwd()
chdir(relative_dirname)
string absolute_dirname=getcwd()
chdir(cwd)
string absolute_filename=absulute_dirname + separator + basename

but note: I am not quite sure if there are issues when symbolic links come into play.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top