Hmm. This does mean that you necessarily do two passes through the
string; an in-place operation only has to do one.
ERROR: Premature optimization leads to sloppy development.
If you're writing a parser that has no use for white space then just
program it to skip over it. You shouldn't have to move any bytes AT
ALL to parse a string with white space in it.
This is incorrect. The original trim() trims only left and right whitespace,
NOT whitespace in the middle of the string.
Ah, true, I made the assumption that it was meant to trim spaces off
command line args for some reason. Simple enough to fix, basically
you want to trim spaces off the start until you hit a non-space, then
scan backwards. So it becomes
char *trim(const char *src)
{
char *tmpdst, *dst = calloc(1, strlen(src + 1));
if (!dst) return NULL;
tmpdst = dst;
while (isspace(*src)) { ++src; }
strcpy(dst, src);
tmpdst = &dst[strlen(dst)-1];
while (isspace(*tmpdst)) { *tmpdst-- = 0; }
return dst;
}
I'd use a macro for the space test [isspace for instance].
And at this point, you're iterating over the whole string once to calculate
its length inside trim, once to copy it, twice for the assert, once for
the strcpy...
Except where is this being used? I'd argue for the sake of command
line parsing who cares? It's a wasted optimization cycle. If I were
writing a parser I'd just make the FSM handle white space and not do
any sort of formatting.
That's what separates a developer from a coder. In 27 lines of code
[both functions] I replaced what took him 100s of lines. And my
version has error checking, uses standard C functions, is portable,
and is plenty easy to read.
And which doesn't do what it's supposed to do.
If you look at all the examples and test cases in the thread, they're
consistent that " foo bar " => "foo bar", not "foobar".
My bad, I misfigured out what he was trying to do. Hell even if done
in place the fix becomes
void trim(const char *str)
{
char *tmpsrc;
// trim leading spaces
tmpsrc = src;
while (isspace(*src)) { ++src; }
if (!*src) {
*tmpsrc = 0;
return;
}
memmove(tmpsrc, src, strlen(src)+1);
// trim trailing spaces
tmpsrc = &tmpsrc[strlen(tmpsrc)-1];
while (isspace(*tmpsrc)) { *tmpsrc-- = 0; }
}
Which with comments is still only a dozen lines long. So it's both
comparable to what he's doing and 6 times smaller.
Tom