Is this an efficient and safe way to grab front part of a string

A

Angus

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};
strcpy(szPath, argv[0]);
char* p = szPath;

size_t len = strlen(argv[0]);
p+=len; //go to end of string

int backpos = 0;
while(*--p != '\\')
++backpos;

szPath[len-backpos] = 0;

printf("%s\n", szPath);

return 0;
}
 
E

Eric Sosman

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.
 
P

Paul N

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?

Just one style point, in addition to what the others have said:
#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[]) {

    char szPath[260] = {0};
    strcpy(szPath, argv[0]);
    char* p = szPath;

    size_t len = strlen(argv[0]);

I would use "szPath" here, rather than "argv[0]". Once you've made a
copy of the thing you want, it seems more natural (and may be safer if
you modify the code later) to concentrate on the thing you're actually
working on rather than keep looking back to where it came from.
 
D

David Thompson

Hello

I need to grab the first part of a string up till and including the
last backslash in a path.
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.
<snip other good points>

Also note that argv[0] is the 'name' of the program being run, but not
necessarily its full pathname. As Eric says, the standard allows it to
be null, but I don't believe any Windows implementation does so (and
Windows is the only platform I know of where \ is a path separator).

If you intended to do this operation on a pathname provided as an
argument to your program, use argv[1] after checking argc.

<OT++>
If you intended to do this on the program path, you probably need to
use GetModuleFilename instead.

<OT++>
And if you intended to do this on the program path to find a directory
to put writable data, don't. Windows officially dislikes that, even
though people did it a lot, and recent generations (>=Vista) are
stricter about it. Submit to the will of Bill and use envvar APPDATA
or similar. For installed read-only data, like a help file, it's okay.
 

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,777
Messages
2,569,604
Members
45,234
Latest member
SkyeWeems

Latest Threads

Top