Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C
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:
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 19-Sep-12 10:54am
DanDv242
Edited 20-Sep-12 5:39am
v5
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

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
handle_text( "  Hello World  " );
and
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
char st[] = "  Hello World  ";
 
handle_text( st );
will work.
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

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.
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

Your solution is very buggy. Here is a good one:
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.
  Permalink  

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

  Print Answers RSS
0 Sergey Alexandrovich Kryukov 450
1 OriginalGriff 230
2 DamithSL 150
3 Dave Kreskowiak 120
4 Suvendu Shekhar Giri 110
0 OriginalGriff 7,740
1 DamithSL 5,644
2 Sergey Alexandrovich Kryukov 5,404
3 Maciej Los 5,011
4 Kornfeld Eliyahu Peter 4,539


Advertise | Privacy | Mobile
Web03 | 2.8.141223.1 | Last Updated 20 Sep 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100