[ACCEPTED]-Remove extra white space from inside a C string?-whitespace

Accepted answer
Score: 11

If I may voice the "you're doing it wrong" opinion, why 8 not just eliminate the whitespace while 7 reading? Use fscanf("%s", string); to read a "word" (non whitespace), then 6 read the whitespace. If it's spaces or tabs, keep 5 reading into one "line" of data. If it's 4 a newline, start a new entry. It's probably 3 easiest in C to get the data into a format 2 you can work with as soon as possible, rather 1 than trying to do heavy-duty text manipulation.

Score: 5

Why not use strtok() directly? No need to modify 3 the input

All you need to do is repeat strtok() until 2 you get 3 non-space tokens and then you 1 are done!

Score: 2

Edit: I originally had a malloced workspace, which 4 I though might be clearer. However, doing 3 it w/o extra memory is almost as simple, and I'm 2 being pushed that way in comments and personal 1 IMs, so, here comes...:-)

void squeezespaces(char* row, char separator) {
  char *current = row;
  int spacing = 0;
  int i;

  for(i=0; row[i]; ++i) {
    if(row[i]==' ') {
      if (!spacing) {
        /* start of a run of spaces -> separator */
        *current++ = separator
        spacing = 1;
      }
    } else {
      *current++ = row[i];
      spacing = 0;
  }
  *current = 0;    
}
Score: 2

The following code modifies the string in 4 place; if you don't want to destroy your 3 original input, you can pass a second buffer 2 to receive the modified string. Should be 1 fairly self-explanatory:

#include <stdio.h>
#include <string.h>

char *squeeze(char *str)
{
  int r; /* next character to be read */
  int w; /* next character to be written */

  r=w=0;
  while (str[r])
  {
    if (isspace(str[r]) || iscntrl(str[r]))
    {
      if (w > 0 && !isspace(str[w-1]))
        str[w++] = ' ';
    }
    else
      str[w++] = str[r];
    r++;
  }
  str[w] = 0;
  return str;
}

int main(void)
{
  char test[] = "\t\nThis\nis\ta\b     test.";
  printf("test = %s\n", test);
  printf("squeeze(test) = %s\n", squeeze(test));
  return 0;
}
Score: 1
char* trimwhitespace(char *str_base) {
    char* buffer = str_base;
    while((buffer = strchr(str_base, ' '))) {
        strcpy(buffer, buffer+1);
    }

    return str_base;
}

0

Score: 0

You could read a line then scan it to find 11 the start of each column. Then use the column 10 data however you'd like.

#include <stdio.h>
#include <string.h>
#include <ctype.h>

#define MAX_COL 3
#define MAX_REC 512

int main (void)
{
    FILE *input;
    char record[MAX_REC + 1];
    char *scan;
    const char *recEnd;
    char *columns[MAX_COL] = { 0 };
    int colCnt;

    input = fopen("input.txt", "r");

    while (fgets(record, sizeof(record), input) != NULL)
    {
        memset(columns, 0, sizeof(columns));  // reset column start pointers

        scan = record;
        recEnd = record + strlen(record);

        for (colCnt = 0; colCnt < MAX_COL; colCnt++ )
        {
          while (scan < recEnd && isspace(*scan)) { scan++; }  // bypass whitespace
          if (scan == recEnd) { break; }
          columns[colCnt] = scan;  // save column start
          while (scan < recEnd && !isspace(*scan)) { scan++; }  // bypass column word
          *scan++ = '\0';
        }

        if (colCnt > 0)
        {
            printf("%s", columns[0]);
            for (int i = 1; i < colCnt; i++)
            {
             printf("#%s", columns[i]);
            }
            printf("\n");
        }
    }

    fclose(input);
}

Note, the code could 9 still use some robust-ification: check for 8 file errors w/ferror; ensure eof was hit 7 w/feof; ensure entire record (all column 6 data) was processed. It could also be made 5 more flexible by using a linked list instead 4 of a fixed array and could be modified to 3 not assume each column only contains a single 2 word (as long as the columns are delimited 1 by a specific character).

Score: 0

Here's an alternative function that squeezes 2 out repeated space characters, as defined 1 by isspace() in <ctype.h>. It returns the length of the 'squidged' string.

#include <ctype.h>

size_t squidge(char *str)
{
    char *dst = str;
    char *src = str;
    char  c;
    while ((c = *src++) != '\0')
    {
        if (isspace(c))
        {
            *dst++ = ' ';
            while ((c = *src++) != '\0' && isspace(c))
                ;
            if (c == '\0')
                break;
        }
        *dst++ = c;
    }
    *dst = '\0';
    return(dst - str);
}

#include <stdio.h>
#include <string.h>

int main(void)
{
    char buffer[256];
    while (fgets(buffer, sizeof(buffer), stdin) != 0)
    {
        size_t len = strlen(buffer);
        if (len > 0)
            buffer[--len] = '\0';
        printf("Before: %zd <<%s>>\n", len, buffer);
        len = squidge(buffer);
        printf("After:  %zd <<%s>>\n", len, buffer);
    }
    return(0);
}
Score: 0

I made a small improvment over John Bode's 1 to remove trailing whitespace as well:

#include <ctype.h>

char *squeeze(char *str)
{
  char* r; /* next character to be read */
  char* w; /* next character to be written */
  char c;
  int sp, sp_old = 0;

  r=w=str;

  do {
    c=*r;
    sp = isspace(c);
    if (!sp) {
      if (sp_old && c) {
        // don't add a space at end of string
        *w++ = ' ';
      }
      *w++ = c;
    }
    if (str < w) {
      // don't add space at start of line
      sp_old = sp;
    }
    r++;
  }
  while (c);

  return str;
}

#include <stdio.h>

int main(void)
{
  char test[] = "\t\nThis\nis\ta\f     test.\n\t\n";
  //printf("test = %s\n", test);
  printf("squeeze(test) = '%s'\n", squeeze(test));
  return 0;
}

br.

Score: 0

The following code simply takes input character 6 wise, then check for each character if there 5 is space more than once it skips it else 4 it prints the character. Same logic you 3 can use for tab also. Hope it helps in solving 2 your problem. If there is any problem with 1 this code please let me know.

    int c, count = 0;
    printf ("Please enter your sentence\n");
    while ( ( c = getchar() ) != EOF )  {
        if ( c != ' ' )  {
            putchar ( c );
            count = 0;
        }
        else  {
            count ++;
            if ( count > 1 )
                ;    /* Empty if body */
            else
                putchar ( c );
         }
     }
}

More Related questions