Eric Sosman
9/3/2011 6:39:00 PM
On 9/3/2011 2:14 PM, Angus wrote:
> Hello
>
> I need to grab the first part of a string up till and including the
> last backslash in a path. I am fairly new to C so was wondering if
> the following code is a good approach?
>
> #include<stdio.h>
> #include<string.h>
>
> int main(int argc, char* argv[]) {
>
> char szPath[260] = {0};
Efficiency: Since the very next thing you do is overwrite whatever's
in the array, initializing it is pointless.
> strcpy(szPath, argv[0]);
Safety: If strlen(argv[0]) > 259 you're in trouble (see "buffer
overflow"). Also, it is just barely possible that argv[0] could be
NULL, so checking for that would make your code (marginally) safer.
> char* p = szPath;
>
> size_t len = strlen(argv[0]);
> p+=len; //go to end of string
>
> int backpos = 0;
> while(*--p != '\\')
> ++backpos;
Safety: If the string contains no '\\' characters at all, you
will walk merrily off the beginning and go traipsing through whatever
happens to lie in adjoining memory. With unpredictable consequences.
Efficiency: Check your C reference for the strrchr() function
(that's three r's, not two).
> szPath[len-backpos] = 0;
>
> printf("%s\n", szPath);
Efficiency: If you just need to print this prefix, as opposed
to using it for other purposes, there's a way to do it without making
a copy and without modifying the string argv[0] points to (which would
be un-safe). Suppose, after a little rummaging around, you have found
that there are prefix_len characters before the rightmost '\\':
int prefix_len = ...;
printf ("%.*s\n", prefix_len+1, argv[0]);
You'll probably find this in your C reference, although you may have
to look closely at the fine print. The "dot something" specifies the
so-called _precision_ of the conversion, which for "%s" means the
maximum number of characters printed, so "%.3s" prints at most three
characters, "%.42s" forty-two, and so on. The "*" means "get this
number from the argument list instead of from digits in the format
string," so in effect it makes prefix_len+1 part of the format.
> return 0;
> }
--
Eric Sosman
esosman@ieee-dot-org.invalid