The code I came up with for the problem was:
static
void removeExtraWhiteSpace(char *src, char *dst)
{
while (*src != '\0')
{
if (!isspace((unsigned char)*src))
*dst++ = *src++;
else
{
*dst++ = ' ';
while (isspace((unsigned char)*src))
src++;
}
}
*dst = '\0';
}
For each character, if it isn't a space according to isspace()
from <ctype.h>
, copy it to the output. If it is a space, copy a space to the output, and skip over any following space characters. When finished, add the null terminator.
The function is static
because I make all functions static
unless there's a header that declares the function for use in other files — the compilation options I use require this discipline (or a prior extern void removeExtraWhiteSpace(char *src, char *dst)
declaration for the function — but static
is shorter.
If you want to remove leading and trailing blanks, it isn't much harder:
static
void removeExtraWhiteSpace(char *src, char *dst)
{
char *tgt = dst;
while (isspace((unsigned char)*src))
src++;
while (*src != '\0')
{
if (!isspace((unsigned char)*src))
*tgt++ = *src++;
else
{
*tgt++ = ' ';
while (isspace((unsigned char)*src))
src++;
}
}
*tgt = '\0';
if (tgt > dst && tgt[-1] == ' ')
tgt[-1] = '\0';
}
Test code:
static void test_string(char *buffer1)
{
printf("Before [%s]\n", buffer1);
char buffer2[1024];
removeExtraWhiteSpace(buffer1, buffer2);
printf("After [%s]\n", buffer2);
}
int main(void)
{
test_string("example\tinput\tstring");
test_string("example\ninput\nstring");
test_string("example \tinput \n string");
test_string(" \t spaces\t \tand tabs\tboth before\t\tand \t \t after \t\t ");
#ifdef GO_INTERACTIVE
char buffer[1024];
while (fgets(buffer, sizeof(buffer), stdin) != 0)
{
buffer[strcspn(buffer, "\n")] = '\0';
test_string(buffer);
}
#endif /* GO_INTERACTIVE */
return 0;
}
Plain output:
Before [example input string]
After [example input string]
Before [example
input
string]
After [example input string]
Before [example input
string]
After [example input string]
Before [ spaces and tabs both before and after ]
After [ spaces and tabs both before and after ]
With tabs and newlines marked (^I for tabs, ^J for newlines):
Before [example^Iinput^Istring]^J
After [example input string]^J
Before [example^J
input^J
string]^J
After [example input string]^J
Before [example ^Iinput ^J
string]^J
After [example input string]^J
Before [ ^I spaces^I ^Iand tabs^Iboth before^I^Iand ^I ^I after ^I^I ]^J
After [ spaces and tabs both before and after ]^J