How to get filename from path in C++

A

Aaron Gray

Whats the best way to get the filename from a path using std::string and
using char[] ?

Many thanks in advance,

Aaron
 
P

Pavel

Daniel said:
Aaron Gray said:
Whats the best way to get the filename from a path using std::string and
using char[] ?

Many thanks in advance,

Sound a lot like a homework problem... Start from the end of the string
and work your way forward looking for the path separator character.
To me it sounded more like asking for a standard library facility that
would do the job. Something like File::Spec in Perl or java.io.File in
Java or basename/dirname in shell, you know..

I guess, everybody's hearing is different.. I am programming in C++ for
some two decades and it is still a puzzle to me how the people in charge
of the standard library select priorities. BTW, does anybody know if
such a basic facility (working with file names) is going to be
standardized in C++0x? Or does that new semantics for square brackets
trample everything? (obviously the past decade was the decade of angle
brackets, but now the squares rule, I guess. If I am still around I may
learn whole new story about parentheses in C++1y -- how exciting!).

-Pavel
std::string already has a member function to do it, and there is a
function in the <cstring> header to handle the char[].

Good luck.
 
F

Fred Zwarts

Aaron Gray said:
Whats the best way to get the filename from a path using std::string and
using char[] ?

This is not really a C++ question. It depends very much on the operating system.
Usually operating system dependent file-name parsing functions are used.
 
F

Fred Zwarts

Pavel said:
Daniel said:
Aaron Gray said:
Whats the best way to get the filename from a path using std::string and
using char[] ?

Many thanks in advance,

Sound a lot like a homework problem... Start from the end of the string
and work your way forward looking for the path separator character.
To me it sounded more like asking for a standard library facility that
would do the job. Something like File::Spec in Perl or java.io.File in
Java or basename/dirname in shell, you know..

I guess, everybody's hearing is different.. I am programming in C++ for
some two decades and it is still a puzzle to me how the people in charge
of the standard library select priorities. BTW, does anybody know if
such a basic facility (working with file names) is going to be
standardized in C++0x? Or does that new semantics for square brackets
trample everything? (obviously the past decade was the decade of angle
brackets, but now the squares rule, I guess. If I am still around I may
learn whole new story about parentheses in C++1y -- how exciting!).

Maybe it is nice to know that in the OpenVMS operating system
square brackets and angle brackets are both used as alternatives to
indicate the directories in a full file path. :)
 
F

Fred Zwarts

Daniel T. said:
Aaron Gray said:
Whats the best way to get the filename from a path using std::string and
using char[] ?

Many thanks in advance,

Sound a lot like a homework problem... Start from the end of the string
and work your way forward looking for the path separator character.

std::string already has a member function to do it, and there is a
function in the <cstring> header to handle the char[].

This assumes that there is only one path separator. There are operating systems that use more.
E.g., OpenVMS starts the directory part of the path with one character, separates the sub-directories
with a second separator and ends the directories with a third one. It further has other characters
to separate the device part and the file version number from the file name. Strange enough it uses
the same character for separating sub-directories and for separating the file name from the file extension.
E.g.: USERDISK:[HOME.USER.SANDBOX]FILENAME.EXT;17
Given the fact that instead of square brackets also angle brackets can be used
(not to mention the separator for the node name part in a full path for remote file names),
the parsing is very complex.
It can be done with member functions of std:string, but it is much better to use
specific OS functions.
 
B

Bo Persson

Fred said:
Daniel T. said:
Aaron Gray said:
Whats the best way to get the filename from a path using
std::string and using char[] ?

Many thanks in advance,

Sound a lot like a homework problem... Start from the end of the
string and work your way forward looking for the path separator
character.

std::string already has a member function to do it, and there is a
function in the <cstring> header to handle the char[].

This assumes that there is only one path separator.

It also assumes that the OS uses paths. :)

Some do not, like IBM z/OS.
It can be done with member functions of std:string, but it is much
better to use
specific OS functions.

Exactly.


Bo Persson
 
T

tni

Fred said:
Aaron Gray said:
Whats the best way to get the filename from a path using std::string and
using char[] ?

This is not really a C++ question.

It should be. The C++ standard library is incredibly lean in terms of
functionality provided.

There are tons of different libraries that each do there own thing (and
probably even have own string types) for this kind of stuff.


Boost filesystem (it may end up being part of standard C++ one day):
http://www.boost.org/doc/libs/1_39_0/libs/filesystem/doc/index.htm

WxWidgets:
http://docs.wxwidgets.org/stable/wx_wxfilename.html

Qt:
http://doc.trolltech.com/qdir.html
http://doc.trolltech.com/qfileinfo.html
 
J

James Kanze

Fred said:
Aaron Gray said:
Whats the best way to get the filename from a path using
std::string and using char[] ?
This is not really a C++ question.
It should be.

Maybe, but how? To date, I don't think anyone has proposed
anything. (Remember, a standard solution would have to work
when the system didn't have sub-directories, or when it also had
version numbers and such.)
 
M

Michael Doubez

Fred said:
messageWhats the best way to get the filename from a path using
std::string and using char[] ?
This is not really a C++ question.
It should be.

Maybe, but how?  To date, I don't think anyone has proposed
anything.  (Remember, a standard solution would have to work
when the system didn't have sub-directories, or when it also had
version numbers and such.)

There was a filesystem proposal for TR2 based on boost implementation.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1975.html#Header-filesystem-synopsis

It wasn't included into C++0x.
 
A

Aaron Gray

Pavel said:
Daniel said:
Aaron Gray said:
Whats the best way to get the filename from a path using std::string and
using char[] ?

Many thanks in advance,

Sound a lot like a homework problem... Start from the end of the string
and work your way forward looking for the path separator character.

No I am working on a COFF backend and I need to create a module identifier
from the filename.
To me it sounded more like asking for a standard library facility that
would do the job. Something like File::Spec in Perl or java.io.File in
Java or basename/dirname in shell, you know..

I guess, everybody's hearing is different.. I am programming in C++ for
some two decades and it is still a puzzle to me how the people in charge
of the standard library select priorities. BTW, does anybody know if

Yes this is an evident fact. C++ standard libraries suck when it comes to
file handling and sockets.
such a basic facility (working with file names) is going to be
standardized in C++0x? Or does that new semantics for square brackets
trample everything? (obviously the past decade was the decade of angle
brackets, but now the squares rule, I guess. If I am still around I may
learn whole new story about parentheses in C++1y -- how exciting!).

Maybe it should be suggested.

std::string filename = ...
size_t index = filename.find_last_of('/\\');
char moduleId[18]
filename.copy( moduleId, std::max( 18, filename.size() - index), index);
// throws out_of_range
and there is a function in the <cstring> header to handle the char[].

strrchr, problem is I want it to work on Unix and Windows.

I suppose

char *filename = ....
char *moduleId = std::max( strrchr( filename, '/'), strrchr( filename,
'\\'));
moduleId = moduleId ? moduleId : filename;

I think this second C like version is probably best, but it does not take in
to account a max length of 18.

I was really hoping there were proper API's in place for this. Unix has them
I believe.

Thanks for the pointers Pavel,

Aaron
 
T

tni

James said:
Fred said:
messageWhats the best way to get the filename from a path using
std::string and using char[] ?
This is not really a C++ question.
It should be.

Maybe, but how? To date, I don't think anyone has proposed
anything. (Remember, a standard solution would have to work
when the system didn't have sub-directories, or when it also had
version numbers and such.)

It doesn't have to work everywhere. It's not like current compilers
support all of the C++ standard. If you have some exotic system, you
just have to do something platform specific (like you have to do today).
Something like versioning could certainly be mapped to paths, e.g. look
at Clearcase.
 
M

Michael Doubez

James said:
Fred Zwarts wrote:
messageWhats the best way to get the filename from a path using
std::string and using char[] ?
This is not really a C++ question.
It should be.
Maybe, but how?  To date, I don't think anyone has proposed
anything.  (Remember, a standard solution would have to work
when the system didn't have sub-directories, or when it also had
version numbers and such.)

It doesn't have to work everywhere.

Then it is not C++ standard compliant.
It's not like current compilers
support all of the C++ standard. If you have some exotic system, you
just have to do something platform specific (like you have to do today).

Some compiler may not be fully standard compliant but it is nor
something to aim at.
Something like versioning could certainly be mapped to paths, e.g. look
at Clearcase.

I expect the program could check for conformance/portability or verify
abstraction supported by the filesystem (on a path).
 
B

Bo Persson

tni said:
James said:
Fred Zwarts wrote:
messageWhats the best way to get the filename from a path using
std::string and using char[] ?
This is not really a C++ question.
It should be.

Maybe, but how? To date, I don't think anyone has proposed
anything. (Remember, a standard solution would have to work
when the system didn't have sub-directories, or when it also had
version numbers and such.)

It doesn't have to work everywhere.

But it is a rather bad standard, if it is not implementable on some
systems. The C and C++ standards go to great lengths not to require
specific pointer formats, 32 bit ints, or IEEE floating point, because
it is known that important systems out there can't support it.

It would be really surprising if the language would then try to
standardize file names and directories.


Bo Persson
 
A

Andreas Dehmel

tni said:
James said:
Fred Zwarts wrote:
messageWhats the best way to get the filename from a path using
std::string and using char[] ?

This is not really a C++ question.

It should be.

Maybe, but how? To date, I don't think anyone has proposed
anything. (Remember, a standard solution would have to work
when the system didn't have sub-directories, or when it also had
version numbers and such.)

It doesn't have to work everywhere.

But it is a rather bad standard, if it is not implementable on some
systems. The C and C++ standards go to great lengths not to require
specific pointer formats, 32 bit ints, or IEEE floating point, because
it is known that important systems out there can't support it.

You seem to suggest that by leaving lots of fundamental concepts
implementation-defined the standard becomes more usable or something.
I'd say that, on the contrary, the only result of this is that rather
than parts of it being unusable on some exotic systems it becomes
unusable everywhere. What good is a standard which doesn't even allow me
to do the most elementary things like a simple portable command line
tool which takes a filename as parameter and does some IO-operation with
that file? If you think that works: think again (Windows on non 8-bit
locales). Yeah, I know, C++0x will address that... at least 10 years
too late, but what the hey...

It would be really surprising if the language would then try to
standardize file names and directories.

Me too, but only because so far the standard seems to have a history
of trying to weasel out of exactly the kind of ugly, low-level
abstractions a standard library should provide first and foremost
of all. Which pretty much forces developers to code outside of the
standard, e.g. using Qt, which (although primarily a GUI-abstraction
layer) does provide things like a _proper_ string class (efficient,
with fully-fledged interfaces to codecs, filesystem etc). In other words
exactly the kind of thing that's indispensable for a _usable_ standard
library.

We'll see about C++0x. Personally, based on past experience, I'm not
holding my breath...



Andreas
 
A

Aaron Gray

Andy Champ said:
Aaron Gray wrote:

My 2c worth:
I'd just like to remind you that in Japan on Windoze the currency
symbol(1) can be used as a path separator. And are those ascii or unicode
or what chars there?

(1) yen symbol, which I can't work out how to type so you'll all be able
to read it - a Y overstruck with an equals sign

Does not really apply to the compiler I am writing the COFF backend for.

Yay,

Aaron
 
B

Bo Persson

Andreas said:
tni said:
James Kanze wrote:
Fred Zwarts wrote:
messageWhats the best way to get the filename from a path using
std::string and using char[] ?

This is not really a C++ question.

It should be.

Maybe, but how? To date, I don't think anyone has proposed
anything. (Remember, a standard solution would have to work
when the system didn't have sub-directories, or when it also had
version numbers and such.)

It doesn't have to work everywhere.

But it is a rather bad standard, if it is not implementable on some
systems. The C and C++ standards go to great lengths not to require
specific pointer formats, 32 bit ints, or IEEE floating point,
because it is known that important systems out there can't support
it.

You seem to suggest that by leaving lots of fundamental concepts
implementation-defined the standard becomes more usable or
something.

Yes, by not specifying everything down to the last bit, the language
is actually usable on a wider range of machines.

Another "totally portable" language needs special hardware add-ons to
run on some machines where C++ runs natively:

http://www-03.ibm.com/systems/z/advantages/zaap/index.html

I'd say that, on the contrary, the only result of this
is that rather than parts of it being unusable on some exotic
systems it becomes unusable everywhere. What good is a standard
which doesn't even allow me to do the most elementary things like a
simple portable command line tool which takes a filename as
parameter and does some IO-operation with that file?

What makes you think that you run command lines on all systems? Not
everything is a desktop.
Me too, but only because so far the standard seems to have a history
of trying to weasel out of exactly the kind of ugly, low-level
abstractions a standard library should provide first and foremost
of all. Which pretty much forces developers to code outside of the
standard, e.g. using Qt, which (although primarily a GUI-abstraction
layer) does provide things like a _proper_ string class (efficient,
with fully-fledged interfaces to codecs, filesystem etc). In other
words exactly the kind of thing that's indispensable for a _usable_
standard library.

Yes, Qt claims "Portability across desktop and embedded systems". What
about everyting else?

This system doesn't even have a GUI:

http://www-03.ibm.com/systems/z/hardware/
We'll see about C++0x. Personally, based on past experience, I'm not
holding my breath...

Please don't.


Bo Persson
 
P

Pavel

Bo said:
Andreas said:
tni wrote:
James Kanze wrote:
Fred Zwarts wrote:
messageWhats the best way to get the filename from a path using
std::string and using char[] ?
This is not really a C++ question.
It should be.
Maybe, but how? To date, I don't think anyone has proposed
anything. (Remember, a standard solution would have to work
when the system didn't have sub-directories, or when it also had
version numbers and such.)
It doesn't have to work everywhere.
But it is a rather bad standard, if it is not implementable on some
systems. The C and C++ standards go to great lengths not to require
specific pointer formats, 32 bit ints, or IEEE floating point,
because it is known that important systems out there can't support
it.
You seem to suggest that by leaving lots of fundamental concepts
implementation-defined the standard becomes more usable or
something.

Yes, by not specifying everything down to the last bit, the language
is actually usable on a wider range of machines.

Another "totally portable" language needs special hardware add-ons to
run on some machines where C++ runs natively:

http://www-03.ibm.com/systems/z/advantages/zaap/index.html

I'd say that, on the contrary, the only result of this
is that rather than parts of it being unusable on some exotic
systems it becomes unusable everywhere. What good is a standard
which doesn't even allow me to do the most elementary things like a
simple portable command line tool which takes a filename as
parameter and does some IO-operation with that file?

What makes you think that you run command lines on all systems? Not
everything is a desktop.
Me too, but only because so far the standard seems to have a history
of trying to weasel out of exactly the kind of ugly, low-level
abstractions a standard library should provide first and foremost
of all. Which pretty much forces developers to code outside of the
standard, e.g. using Qt, which (although primarily a GUI-abstraction
layer) does provide things like a _proper_ string class (efficient,
with fully-fledged interfaces to codecs, filesystem etc). In other
words exactly the kind of thing that's indispensable for a _usable_
standard library.

Yes, Qt claims "Portability across desktop and embedded systems". What
about everyting else?

This system doesn't even have a GUI:

http://www-03.ibm.com/systems/z/hardware/
But it has Java (see same page) which incidentally has the standard API
for dividing a file name onto directory and file name proper and more. I
guess this system is simply not exotic enough.. :).

-Pavel
 
J

James Kanze

"Pavel" <dot_com_yahoo@paultolk_reverse.yourself> wrote in message

[...]
std::string filename = ...
size_t index = filename.find_last_of('/\\');
char moduleId[18]
filename.copy( moduleId, std::max( 18, filename.size() - index), index);
// throws out_of_range
and there is a function in the <cstring> header to handle
the char[].
strrchr, problem is I want it to work on Unix and Windows.

Then you'll need the std::string solution. Windows allows both
'/' and '\' as path separators (and it's not unusual to see
both, depending on the context), so strchr can't be used.

As has been pointed out, other systems have different
conventions. This is the sort of thing that needs to be in a
system dependent library (like the standard library).
 
J

James Kanze

Fred Zwarts wrote:
messageWhats the best way to get the filename from a path using
std::string and using char[] ?
This is not really a C++ question.
It should be.
Maybe, but how? To date, I don't think anyone has proposed
anything. (Remember, a standard solution would have to work
when the system didn't have sub-directories, or when it also had
version numbers and such.)
There was a filesystem proposal for TR2 based on boost
implementation.http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1975.html#He...
It wasn't included into C++0x.

Maybe because it can't be implemented on some platforms, and
doesn't address all of the issues on others. Doing something
that is portable between Windows and Unix is relatively trivial,
but C++ aims to be portable to other systems as well.
 
M

Michael Doubez

Fred Zwarts wrote:
messageWhats the best way to get the filename from a path using
std::string and using char[] ?
This is not really a C++ question.
It should be.
Maybe, but how?  To date, I don't think anyone has proposed
anything.  (Remember, a standard solution would have to work
when the system didn't have sub-directories, or when it also had
version numbers and such.)
There was a filesystem proposal for TR2 based on boost
implementation.http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1975.html#He...
It wasn't included into C++0x.

Maybe because it can't be implemented on some platforms, and
doesn't address all of the issues on others.  Doing something
that is portable between Windows and Unix is relatively trivial,
but C++ aims to be portable to other systems as well.

I agree we cannot ensure portability of filename but perhaps something
could be done to ensure a minimum set of common concept for
manipulating filenames and the underlying ressource.

tr2::filesystem does not seem far from that to me.

It has been accepted into TR2 (at the 2006 Berlin meeting it seems) at
the same time as <error_code> which has been included into C++0x. I
could not find minutes concerning Filesystem.
It is not mentioned in Portland 2006 Meeting:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2122.htm

I guess it is more a resource shortage to address the issue - from BS
interview:
http://www.ddj.com/cpp/207000124?pgno=2
<quote>
B.S.: The progress on standard libraries has not been what I hoped
for. We will get regular expressions, hash tables, threads, many
improvements to the existing containers and algorithms, and a few more
minor facilities. We will not get the networking library, the date and
time library, or the file system library. These will wait until a
second library TR. I had hoped for much more, but the committee has so
few resources and absolutely no funding for library development.
</quote>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top