Separating directory from file name

D

Dan Pop

In said:
I don't know about any standard C answer to the stated problem,
but your example might imply UNIX pathname syntax (although
also acceptend on Windoze, though not on command line).

Even on command line, on modern Windows versions. It's only the good old
COMMAND.COM (R.I.P.) that had a problem with them.
So even
standard C answer (e.g. strrchr(), as suggested) may be platform specific.
If you are on UNIX, there should be basename(3C). For details
see e.g. here:
http://docs.sun.com/db/doc/805-3175/6j31emn1l?a=view#basename-3c-indx-1

My apologies to the group for an OT answer. But in this case I consider
it worth giving. It's not portable, but neither are some others. I've
already
forgotten what path looked like on VAX.

If the VAX was running any flavour of Unix, as quite a lot of them
actually did... ;-)

Just like on Windows, C on VMS was/is perfectly happy with Unix-like path
specifications, dua0:[foo.bar.baz]hello.c being also accepted as
/dua0/foo/bar/baz/hello.c . IIRC, even remote file specifications like
remotehost::dua0:[foo.bar.baz]hello.c could be translated into a Unix-like
path specification: //remotehost/dua0/foo/bar/baz/hello.c . This was also
the native path syntax on Domain/OS, where the // standed for the internet
root directory and the first single / for the host root directory.
Original problem was to extract
file name from the full path name, not to find last '/'.

If you really think that, you're reading impaired. The description of the
original problem is still included at the top of the article and it seems
to have everything to do with finding the last '/' character. And since
this can be trivially achieved in standard C, there is no point in
recommending anything else, as long as you do it in comp.lang.c.

Consider the cases when you have to split a Unix path specification on
a non-Unix platform.

Dan
 
J

Joe Laughlin

nobody said:
I don't know about any standard C answer to the stated
problem,
but your example might imply UNIX pathname syntax
(although
also acceptend on Windoze, though not on command line).
So even
standard C answer (e.g. strrchr(), as suggested) may be
platform specific. If you are on UNIX, there should be
basename(3C). For details
see e.g. here:
http://docs.sun.com/db/doc/805-3175/6j31emn1l?a=view#basename-3c-indx-1

My apologies to the group for an OT answer. But in this
case I consider it worth giving. It's not portable, but
neither are some others. I've already
forgotten what path looked like on VAX. Original problem
was to extract file name from the full path name, not to
find last '/'.

I found what I really wanted... basename() and dirname(). Non-standard C
functions, but perfectly fine for my usage.
 
I

Irrwahn Grausewitz

Chris McDonald said:
Is there something inherently wrong with using standard functions, here,

On the contrary. Alas, it seems to be part of every programmer's
learning curve to, at some point, think he's 'fit' enough to
'outsmart' the library implementer. Most programmers go past this
period very quickly, when they notice they fail miserably (and yes,
I know CBF has moved way beyond this phase many years ago :).
or is this just a macho contest?

Likely.... ;-)

Regards
 
M

Martin Dickopp

Mabden said:
Hey, Martin! I thought you killfiled me over some comedy I posted
once! Did you grow a sensual humor?

In that case, you presumably mistake me for somebody else. I rarely
killfile people (less often than once a year), and when I do that, I
never publically announce it.

I occasionally point out to people that a certain behaviour is likely
to get them killfilled (not necessarily by me). However, unless the
behavior is extremely offending, I instantly forget about it, and
therefore don't recognize such people when they come back and behave
better. Whether I ever have complained about /your/ behavior, I don't
recall.

Martin
 
M

Martin Dickopp

Chris McDonald said:
Is there something inherently wrong with using standard functions,
here, or is this just a macho contest?

Short answer: It's just a macho contest.

Longer answer: A few postings up, somebody pointed out that while the
problem can be easily solved with standard library functions, it is a
good exercise for a beginner to solve it without library functions.
He also posted an example implementation and invited comments.

Martin
 
M

Mabden

Grumble said:
"sensual humor" is that another old-timer joke?

Nope. Just a phrase that popped into my head. Of course, it was more amusing
at 1am after a few...
 
M

Mabden

Dan Pop said:
In <[email protected]> "Mabden" off string.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

What makes you think that strrchr() doesn't work exactly as you have
described above? All the generic C implementations of strrchr() I am
familiar with do a single scan, until they find the null character and
"remember" the last address of the target character.

You are right, Dan, I mixed up what I was saying. What I meant was that if
you take the strlen() of a string, add it to a pointer, and then move
backwards through the string, you are scanning twice.

I didn't mean to say the strchr() itself was a poor implementation -
although I clearly did say that.

I have to agree with whoever said that using common library functions is a
Good Thing, as everyone understands (or can look up) their function.

But if the string parsing is more complicated, one can just as easily write
a loop that scans through the string in one pass and sets a few pointers.

I guess I don't have a good point here, except that rippling through a
string is as easy in a loop as it is to call a function, and if you are
going to the end of the string only to come backwards then maybe you could
re-think what you are doing and make it a one-pass algorithm.
 
K

kal

CBFalconer said:
while the complex single scan is something like:

pp = NULL; p = ptr;
while (*p) {
if ('/' == *p) pp = p;
p++;
}

The following may also work, if somewhat differently.

pp = p = ptr;
while (*p) {
if ('/' == *(p++)) pp = p;
}
 
C

CBFalconer

kal said:
The following may also work, if somewhat differently.

pp = p = ptr;
while (*p) {
if ('/' == *(p++)) pp = p;
}

It will have a one-off error.

Chuck, beating macho breast loudly.
 
I

Irrwahn Grausewitz

CBFalconer said:
It will have a one-off error.

Quite. But interestingly, it might be a perfect solution for
OP's original task ("Separating directory from file name"), in
that it returns a pointer to the character that immediately
follows the last occurrence of '/'.
Chuck, beating macho breast loudly.

Don't hurt yourself too bad... ;D

Regards
 
K

Kieran Simkin

When posting my code I was aware of strrchr() and wasn't under any delusions
of being able to beat the standard libs. It was more just a programming
exercise for myself. It turned out I actually needed to do something similar
for a project I'm working on today.

I needed a function to take a unix pathname like "/home/foo/dir/subdir/" and
create any necessary directories that didn't already exist in the path. For
example /home/foo may exist, but dir and dir/subdir might not. Here's the
code I came up with: (only non-standard functions here are mkdir() and
direxists() and they're not really part of the text processing algorithm).

int mkrdir (const char *dir, const int mode) {
char *tdir,*pnam;
/* ideally this strlen() would not be necessary, but I didn't want
to use a fixed buf */
pnam = malloc(strlen(dir)+1);
if (pnam == NULL) {
return 1;
}
tdir=pnam;
while(*dir != '\0') {
if (*dir == '/') {
*(tdir+1)='\0';
if (strcmp(pnam,"")!=0) {
if (!direxists(pnam)) {
mkdir(pnam,mode);
}
}
}
*(tdir++)=*(dir++);
}
*tdir='\0';
if (*(tdir-1) != '/') {
mkdir(pnam,mode);
}
tdir=NULL;
free(pnam);
return 0;
}


--


~Kieran Simkin
Digital Crocus
http://digital-crocus.com/
 
N

nobody

Dan Pop said:
In <[email protected]> "nobody"
Even on command line, on modern Windows versions. It's only the good old
COMMAND.COM (R.I.P.) that had a problem with them.

Maybe that depends on definition of "modern". It doesn't work on NT 4.0
and I believe neither on 2K (don't have one on hand):

Microsoft(R) Windows NT(TM)
(C) Copyright 1985-1996 Microsoft Corp.

C:\users>cd \temp

C:\TEMP>cd /users
The syntax of the command is incorrect.

C:\TEMP>cd \users

C:\users>

[interesting info snipped]
Thanks for clarification on VMS. It was *long* time when I've dealt with it.
If you really think that, you're reading impaired. The description of the
original problem is still included at the top of the article and it seems
to have everything to do with finding the last '/' character.

I *might* be reading impaired, but I still didn't get it why you my think so
based on OP and my assertions. Description of the problem seems to to have
everything to do with extracting file name from path name. Finding of last
'/'
is part of one of the solutions, but not a problem definition itself.

[snip]
 
D

Dan Pop

In said:
I needed a function to take a unix pathname like "/home/foo/dir/subdir/" and
create any necessary directories that didn't already exist in the path. For
example /home/foo may exist, but dir and dir/subdir might not. Here's the
code I came up with: (only non-standard functions here are mkdir() and
direxists() and they're not really part of the text processing algorithm).

There is a standard C function that provides the complete solution
(albeit not portably to non-Unix systems):

system("mkdir -p /home/foo/dir/subdir");

Dan
 
D

Dan Pop

In said:
Maybe that depends on definition of "modern". It doesn't work on NT 4.0
and I believe neither on 2K (don't have one on hand):

Microsoft(R) Windows NT(TM)
(C) Copyright 1985-1996 Microsoft Corp.

C:\users>cd \temp

C:\TEMP>cd /users
The syntax of the command is incorrect.

C:\TEMP>cd \users

C:\users>

That's because you're using it incorrectly, i.e. in contexts where the /
character has different semantics. Use it in contexts where there are no
such conflicts and it works:

T:\>h:/test
0000:0004

This command has executed the file H:\TEST.EXE.
I *might* be reading impaired, but I still didn't get it why you my think so
based on OP and my assertions. Description of the problem seems to to have
everything to do with extracting file name from path name. Finding of last
'/'
is part of one of the solutions, but not a problem definition itself.

Feel free to provide a portable solution (i.e. a solution suitable for
this newsgroup) that is not based on finding of the last /.

Dan
 
S

Shuvodeep

Hey u can always use strrchr function supplied with string.h
library...if u r using Microsoft C/Turbo C
 
K

kal

Hey u can always use strrchr function supplied with string.h
library...if u r using Microsoft C/Turbo C

1. My understanding is that "top posting" is bad manners here.

2. File name manipulation is related to file system and hence
is off topic. Here the discussion is about how to do it
in standard C assuming a certain file naming convention.

3. If you are using any of the C compilers you mentioned then
try looking up the "_makepath" and "_splitpath" functions.
 
C

CBFalconer

kal said:
(e-mail address removed) (Shuvodeep) wrote in message


1. My understanding is that "top posting" is bad manners here.

In addition silly obfuscative abbreviations such as "u r" are
considered childish and strongly discouraged. string.h is NOT a
library. It is normally a system header file, used to secure
proper declarations of various routines included in the standard
library.
 
C

Charles Richmond

Joe said:
If I have a character array with "/some/file/directory/file_name", are there
any functions / libraries that I could use to separate the directory
("some/file/directory") from the file name ("file_name").

I looked at sscanf(), but that didn't seem to do what I wanted.
If you are using Linux or Unix, there should be a function available
to separate out the file name from the path-filename combination.

--
+-------------------------------
| Charles and Francis Richmond
| richmond at plano dot net
| Re-Defeat Bush!!!
+-------------------------------
 
P

pete

Joe said:
If I have a character array with
"/some/file/directory/file_name", are there
any functions / libraries that I could use to separate the directory
("some/file/directory") from the file name ("file_name").

I looked at sscanf(), but that didn't seem to do what I wanted.

/* BEGIN new.c */

#include <stdio.h>
#include <string.h>

int main(void)
{
puts(1 + strrchr("/some/file/directory/file_name", '/'));
return 0;
}

/* END new.c */
 

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
474,143
Messages
2,570,822
Members
47,368
Latest member
michaelsmithh

Latest Threads

Top