www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2001/06/19/00:46:59

From: Jack Klein <jackklein AT spamcop DOT net>
Newsgroups: comp.os.msdos.djgpp
Subject: Re: Extracting a directory name.
Message-ID: <2vktit40avllhv0f8p788kura4pshfe5d9@4ax.com>
References: <u0pX6.32176$9t5 DOT 2935940 AT news6-win DOT server DOT ntlworld DOT com>
X-Newsreader: Forte Agent 1.8/32.548
MIME-Version: 1.0
Lines: 71
Date: Tue, 19 Jun 2001 04:32:36 GMT
NNTP-Posting-Host: 12.84.2.221
X-Complaints-To: abuse AT worldnet DOT att DOT net
X-Trace: bgtnsc04-news.ops.worldnet.att.net 992925156 12.84.2.221 (Tue, 19 Jun 2001 04:32:36 GMT)
NNTP-Posting-Date: Tue, 19 Jun 2001 04:32:36 GMT
Organization: AT&T Worldnet
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

On Mon, 18 Jun 2001 16:22:10 +0100, "Graham Reeds"
<grahamr AT ntlworld DOT com> wrote in comp.os.msdos.djgpp:

> I have a piece of code which isn't working, and I can't think for the life
> of me why.  I have isolated the fault down to these lines with my
> error-checking (printf()s) still in:
> 
>     Ptr = strrchr(Directory, '\\');
>     bytestocopy = strlen(Directory) - strlen(Ptr);
>     printf("%i\n", bytestocopy);
>     strcpy(FileName, Ptr+1);
>     strncpy(BaseDir, Directory, bytestocopy);
>     printf("BaseDir: %s (%li)\n", BaseDir, strlen(BaseDir));
> 
> All the code does is take in a Directory (i.e:  'temp\downloads' or
> 'temp\downloads\images') and return the last path after the slash (using the
> previous examples 'downloads' and 'images').  This works.  However I also
> need the info before the slash, and this is the piece that isn't working.
> The amount to copy is strlen(Directory) - strlen(Ptr) but for some reason
> always appends 2 extra bytes to the end or assorted gibberish (in the first
> example I've got 'tempÛç').  I've tried to append a null byte to terminate
> it with strcat() but that doesn't do anything either. I've got a feeling
> I've probably missed something very basic, and it is beginning to frustrate
> me.
> 
> Any ideas why?

The easiest way to do this is to strcpy() the original pointer into
the destination string first.  Then do your strrchr() and get a
pointer to the final \ and (after checking for NULL, of course), use
the pointer to write a '\0' over the back slash.  Then you can copy
the rest of the name you want over it.

If you want to stick with your method you have to avoid the quirk in
the C library function strncpy().  This function always copies exactly
the number of characters you specify to the destination.  If the
source has fewer characters, strncpy() adds however many '\0'
characters are needed to fill out the number.  If the source has as
many characters as you specified to copy (or more), then strncpy()
does not add a '\0' to make the destination a proper string.

On the other hand, strncat() does not have this problem (it adds a
'\0' to the destination even after copying the full number of chars),
but it does require a '\0' terminated string to append to.

So you can replace your: 

   strncpy(BaseDir, Directory, bytestocopy);

...with this:

   BaseDir[0] = '\0';
   strncat(BaseDir, Directory, bytestocopy);

...and it will do what you want.

BTW, the portable way to print a size_t value in C (the type returned
by strlen()) is to cast it to unsigned long:

printf("%lu\n", (unsigned long)strlen(some_string));

The use of "%li" happens to work on many implementations but is not
guaranteed to be portable and will break hideously on some.

-- 
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019