This function trims leading and trailing spaces from a string, in place.
I wonder if it can be simplified, without sacrificing efficiency, but I
don't see how.
[...]
Perhaps is better to use memmove to avoid this situation:
FWIW, you can check this crude code out for a moment:
________________________________________________________________
#define xisspace(c) isspace((unsigned char)(c))
char*
string_trim_counted(char* str, char** pend, size_t length)
{
char* start = str;
while (*start && xisspace(*start))
{
start++;
}
if (*start)
{
char* end = str + (length - 1);
while (end != str && xisspace(*end))
{
--end;
}
*pend = end + 1;
}
else
{
*pend = start;
}
return start;
}
char*
string_trim_zeroterm(char* str, char** pend)
{
char* start = str;
while (*start && xisspace(*start))
{
start++;
}
if (*start)
{
char* end = start;
char* pos = start + 1;
while (*pos)
{
if (! xisspace(*pos))
{
end = pos;
}
++pos;
}
*pend = end + 1;
}
else
{
*pend = start;
}
return start;
}
________________________________________________________________
These functions don't actually mutate the buffer. Instead, they return a
pointer to the start and end of the trimmed sub-string. You could them like:
<pseudo-code>
________________________________________________________________
void
printf_trimmed_string(char* str)
{
char* end;
char* start = string_trim_zeroterm(str, &end);
char tmp = *end;
*end = '\0';
printf("trimmed string: ->|%s|<-\n"
"length : %lu\n",
start,
(unsigned long int)(end - start));
*end = tmp;
}
void
foo(void)
{
char str[] = " xx x x x x x x x x ";
puts_trimmed_string(str);
}
________________________________________________________________
Also, if you know the length of the string you want to trim, call
`string_trim_counted()' instead because it's more scaleable and efficient
than the version that does not accept a string length.