Click here to Skip to main content
15,886,199 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi, I am trying to code a function that removes certain characters of choice from a string. In my case I am trying to "merge" whitespaces, meaning that if there are multiple consequent whitespaces in a string, one will be left.
For example: The string " Hello World " (multiple consequent spaces before Hello and after World, for some reason not seen here), entered into my function will become " Hello World ". The function returns the number of characters removed.

The function that I wrote is this:
C#
int handle_text(char *st)
{
    int size = strlen(st);
    int space = 0;
    char* newst = st;
    for (int i = 0, j=0; i < size; i++ )
    {
        if (st[i] != ' ')
        {
            newst[j] = st[i];
            space = 0;
            j++;
        }
        else if (!space)
        {
            newst[j]=' ';
            space = 1;
            j++;
        }
        
    }
    newst[j]='\0';
    return (size-strlen(newst));
}


The problem is that the function cannot write or change the original string. In the line: newst[j]=' '; the program crashes. (newst points to the same as st).
I also tried starting newst as a different pointer, and in the end making st point to where newst is pointing, but the effect is not seen outside the function.

PS: Overall complexity should be O(n);
Posted
Updated 20-Sep-12 4:39am
v5

I am assuming your program crashes with an "Access violation writing location...".

This is caused because the handle_text function is called with a string that cannot be changed.
Calling the function like
C++
handle_text( "  Hello World  " );
and
C++
char* st = "  Hello World  ";

handle_text( st );
will cause the access violation. This is because these string literals are stored in read only memory and any attempt trying to alter them will result in the access violation.

However calling it like
C++
char st[] = "  Hello World  ";

handle_text( st );
will work.
 
Share this answer
 
The simplest solution is this: start at the character you want to remove (let's call it position i), rewrite it with the character at i + 1, and repeat for every character after it. Don't forget to skip the last item, because there is nothing after it!

An array is a set size, you can't simply "remove" something from it, because that would decrease the size, so instead you accomplish this by rewriting every value from the one you want to remove to the end with the next item.
 
Share this answer
 
Your solution is very buggy. Here is a good one:
C++
int handle_text(char* st)
{
	int space = 0;
	char* newst = st;
	for (; st[0]; ++st)
	{
		if (st[0] != ' ')
		{
			newst[0] = st[0];
			++newst;
			space = 0;
		}
		else if (!space)
		{
			newst[0] = st[0];
			++newst;
			space = 1;
		}
	}
	newst[0] = 0;
	return (int)(st - newst);
}

int main()
{
	char TXT[] = "Less  space  is  better.";
	int removed = handle_text(TXT);
	printf("%d %s\n", removed, TXT);
	return 0;
}

Note that calling strlen() isn't needed because you always have to walk through the original string from beginning to end without the need to know the full length. Another thing that makes you code slow and also buggy is that you always write a zero to the end of the string in every iteration in your code. Its enough to zero terminate the destination string only when the iteration is finished. Note that in my solution after the iteration the source pointer points to the zero terminator of the source string hile the newst pointer points to the zero terminator of the dest string. Subtracting them gives the difference in their length.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900