Sam Thers
Sam Thers

Reputation: 67

Deleting whitespace up to first valid character C

I basically have want to remove all the leading whitespace before the first valid character in an array.

For example if I have something like ' 1.6, 1.7', I want it to be '1.6, 1.7' or if it was just '1.7, 1.8', then it would be '1.7, 1.8'

This is my method for the whitespace, however it only shows where the whitespace are. I need help removing it.

char **storeArray

void Students::removeSpace()
{
   int MAX_SIZE = 30;
   for(int i=0; i<3; i++)
   {
     for(int j=0; j<MAX_SIZE; j++)
     {
        if(isspace(storeArray[i][j]) && !(isspace(storeArray[i][j++])
        {
          // I NEED HELP HERE. I'M TRYING TO REMOVE ALL THE LEADING WHITESPACE ONLY
        }
     }
   }
}

Upvotes: 2

Views: 1239

Answers (4)

David C. Rankin
David C. Rankin

Reputation: 84541

You can either keep strtrimws as a separate function or incorporate its contents within your Students::removeSpace function. The following function can be used with or without assigning the return. Examples: strtrimws (somestring); or char *newstring = strtrimws (somestring); Also note, while the original string 's' is modified by the function, the start address for 's' is unchanged making it safe for use with dynamically allocated strings. Shown below in context with your removeSpace function:

#include <ctype.h>

/** remove leading and trailing whitespace, original not preserved.
 *  this funciton can be used with or without assigning the return.
 */
char *strtrimws (char *s)
{
    char *sp = s;                   /* start pointer to return  */
    char *p = s;                    /* pointer to parse string  */

    while (isspace (*s))  s++;      /* skip leading whitespace  */
    while (*s) *p++ = *s++;         /* reindex s to end         */
    while (isspace (*p)) *p-- = 0;  /* null-terminate from end  */

    return sp;
}

char **storeArray;

void Students::removeSpace()
{
    int i = 0;
    for(int i=0; i<3; i++)
        strtrimws (storeArray[i]);
}

NOTE: if you have initialized all pointers to zero/NULL in storeArray before assigning strings to (some or all) of the pointers-to-char you can simplify/improve removeSpace by eliminating the hardcoded number of iterations for i and replacing it with a simple:

void Students::removeSpace()
{
    int i = 0;
    while (storeArray[i])
        strtrimws (storeArray[i++]);
}

Example of funciton in use:

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

/** remove leading and trailing whitespace, original not preserved.
*  this funciton can be used with or without assigning return.
*/
char *strtrimws (char *s)
{
    char *sp = s;                   /* start pointer to return  */
    char *p = s;                    /* pointer to parse string  */

    while (isspace (*s))  s++;      /* skip leading whitespace  */
    while (*s) *p++ = *s++;         /* reindex s to end         */
    while (isspace (*p)) *p-- = 0;  /* null-terminate from end  */

    return sp;
}

int main (int argc, char **argv)
{
    if (argc < 2) {
        fprintf (stderr, "\n error: insufficient input. Usage:  %s char* char* ... (max 5)\n\n", argv[0]);
        return 1;
    }

    char array[5][50] = {{0}};
    int i = 0;

    for (i = 1; i < argc; i++)
    {
        strncpy (array[i-1], argv[i], strlen (argv[i]));
        printf ("\n array[%d] '%s'\n", i, strtrimws (array[i-1]));
    }

    return 0;
}

output:

$ ./bin/stripwsarray " string 1 ws " "  string 2 ws  " "   string 3 ws   "

 array[0] 'string 1 ws'

 array[1] 'string 2 ws'

 array[2] 'string 3 ws'

Upvotes: 0

Gillespie
Gillespie

Reputation: 6561

Try something like this:

#include <stdio.h>

int main()
{
    char storeArray[20] = "   Check it out.";
    int whitespace = 0;

    printf("%s\n", storeArray);

    //Count leading whitespace
    for(int i=0; i<20; i++)
    {
        if(storeArray[i] == ' ' || storeArray[i] == '\t')
            whitespace++;
        else
            break;
    }

    //Shift everything left
    for(int i=0; i<20; i++)
    {
        if (i+whitespace < 20)
            storeArray[i] = storeArray[i+whitespace];
        else
            storeArray[i] = 0;
    }

    printf("%s\n", storeArray);

    return 0;
}

Upvotes: 1

Christophe
Christophe

Reputation: 73366

If you're sure that the c-strings are not longer than MAX_SIZE and if they are null terminated strings:

   for(int i=0; i<3; i++)
   {
     int j=0; 
     while (j<MAX_SIZE && isspace(storeArray[i][j]) 
         j++;
     if (j==MAX_SIZE)  // oops ! Not null terminated and only whitespace ? 
         storeArray[i][0]='\0';
     else if (j>0) // if no leading whiespace do nothing !
         strcpy (storeArray[i], &storeArray[i][j]);    // if you like c style
   } 

If you are working in C++ (as the Student::removeSpace() suggest), and if you really don't want to work with std::string, then you could consider replace all this with:

   for(int i=0; i<3; i++)
       copy(find_if(storeArray[i], storeArray[i] + MAX_SIZE, [](char c){ return c && !isspace(c); }), storeArray[i] + MAX_SIZE, storeArray[i]); 

Edit: If you want to avoid moving your strings, and if you can afford to change the string pointers (i.e.you didn't dynamically allocate the strings), then you could do as well:

   for(int i=0; i<3; i++)
       for (int j=MAX_SIZE-1; j>=0 && isspace(*storeArray[i]); j--) 
           storeArray[i]++;  // no move or copy, but original pointer lost forever

Upvotes: 0

chux
chux

Reputation: 153348

To remove extra white-space, march through the string:

void Remove_Leading_ExtraMiddle_Trailing_Whitespace(char *s, int size) {
  char *end = &s[size];
  char *t = s;
  // skip leading
  while (isspace(*s))
    s++;

  // middle
  for (;;) {
    while (!isspace(*s) && *s != '\0') {
      *t++ = *s++;
    }
    if (*s == '\0')
      break;
    *t = *s++;
    while (isspace(*s))
      s++;
    if (*s == '\0') {
      break;
    }
    t++;
  }

  // end
  while (t < end) {
    *t++ = '\0';
  }
}

void removeSpace() {
  int MAX_SIZE = 30;
  char storeArray[4][MAX_SIZE];
  for (int i = 0; i < 3; i++) {
    Remove_Leading_ExtraMiddle_Trailing_Whitespace(storeArray[i], MAX_SIZE);
  }
}

Upvotes: 2

Related Questions