iharob identified your problem and gave a good solution, but I'd like to show you a slightly different approach.
char *rd; // "read" pointer
char *wr; // "write" pointer
rd = wr = string; // initially, both read and write pointers point to
// beginning of the string
while ( *rd != 0 ) // while not at end of string
{
while ( isspace( *rd ) ) // while rd points to a whitespace character
rd++; // advance rd
*wr++ = *rd++; // copy *rd to *wr, advance both pointers
}
*wr = 0; // terminate the result
printf( "squished: %s\n", string );
Walking through this with the test string "This is a test", we start out as follows (\0 represents the string terminator):
+----------------------- rd
|
V
This is a test\0
^
|
+----------------------- wr
The first four characters aren't whitespace, so we just overwrite those characters with the same values and advance the two pointers, giving us
+------------------- rd
|
V
This is a test\0
^
|
+------------------- wr
Since rd is pointing to whitespace, we continue to advance it until we find a non-whitespace character:
+--------------- rd
|
V
This is a test\0
^
|
+------------------- wr
We then write that non-whitespace character to the location pointed to by wr:
+--------------- rd
|
V
Thisi is a test\0
^
|
+------------------- wr
Keep this up until we find the next whitespace character:
+------------- rd
|
V
Thisis is a test\0
^
|
+----------------- wr
Continue to advance rd to the next non-whitespace character:
+------------ rd
|
V
Thisis is a test\0
^
|
+----------------- wr
Write it to wr:
+------------ rd
|
V
Thisisa is a test\0
^
|
+----------------- wr
Lather, rinse, repeat:
+---- rd
|
V
Thisisatesta test\0
^
|
+------------ wr
rd now points to the end of the string. We exit the main loop and write a 0 to wr to terminate the string:
+---- rd
|
V
Thisisatest\0 test\0
^
|
+------------ wr
I prefer this solution since each character only gets shifted once to its final location. You wind up overwriting characters that you don't need to at the beginning of the string, but I think that's a reasonable tradeoff.
Edit
Chux's version is a bit slicker, and definitely more in the spirit of C:
do
{
while ( isspace( *rd ) ) // while rd points to whitespace
rd++; // advance rd
}
while ( (*wr++ = *rd++) ); // copy rd to wr, advance pointers until
// we see the string terminator
Again, each character only gets shifted once to its final location.
ptr=&str[0];is the same asptr = str;. Also, DO NOT USEgets().gets(), can buffer overflow.fgets(str, sizeof(str), stdin)looks very simple to me., andptr = str;is certainly simpler.