Reputation: 67
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
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
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
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
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