Hello, I have a problem where I need to delete any occurrence of "~" from a string. I created a function but in the end, it only deletes half of the "~" and leaves the other half....

string goodstring(string inp) 
{
	for (int i = 0; i < strlen(inp.c_str()); i++)
	{
		if (inp[i] >= 0x41 && inp[i] <= 0x5A)
		{
			inp[i] += 0x20;
		}
	}

	for (int i = 0; i < strlen(inp.c_str()); i++)
	{
		if (inp[i] >= 32 && inp[i] <= 47)
		{
			inp[i] = 126;
		}
	}

	for (int i = 0; i < strlen(inp.c_str()); i++)
	{
		if (inp[i] >= 58 && inp[i] <= 64)
		{
			inp[i] = 126;
		}
	}

	for (int i = 0; i < strlen(inp.c_str()); i++)
	{
		if (inp[i] >= 91 && inp[i] <= 96)
		{
			inp[i] = 126;
		}
	}

	for (int i = 0; i < strlen(inp.c_str()); i++)
	{
		if (inp[i] >= 123 && inp[i] <= 126)
		{
			inp[i] = 126;
		}
	}

	for (int i = 0; i < strlen(inp.c_str()); i++)
	{
		if (inp[i] >= '0' && inp[i] <= '9')
		{
			inp[i] = 126;
		}
	}

	for (int i = 0; i < strlen(inp.c_str()); i++)
	{
		if (inp[i] == 126)
		{
			inp.erase(inp.begin() + i, inp.begin()+i+1);
		}
	}

	return inp;
}

So what I basically do is read a string, and go like

input = goodstring(input);

Can someone help me sort this problem? Also I just realized that I don't actually need that many for loops.. Sorry.

Recommended Answers

All 6 Replies

I don't know the purpose of all those for loops. If all you want to do is erase the '~' characters then just do that

for(int i = 0; i < inp.length(); i++)
{
   if( inp[i] == '~')
      inp.erase(i,1);
}

I don't know the purpose of all those for loops. If all you want to do is erase the '~' characters then just do that

for(int i = 0; i < inp.length(); i++)
{
   if( inp[i] == '~')
      inp.erase(i,1);
}

That is whats not working. It only deletes half of the "~" symbols..

This is what I already have..

for (int i = 0; i < strlen(inp.c_str()); i++)
	{
		if (inp[i] == 126)
		{
			inp.erase(i, 1);
		}
	}

So if I input "~~~~" then it will only delete two of them not all four of them.

I think its because when you erase the character the next one takes its place and the for loop will not delete the one that takes the deleted one's place...

Here is one way to do it. There may be more effieient methods

string foo(string& inp)
{
    string::iterator it = inp.begin();
    for(; it != inp.end(); it++)
    {
        if( *it == '~')
        {
            inp.erase(it);
            // now restart the loop
            it = inp.begin();
        }
    }
    return inp;
}

int main()
{
    string input = "a~b~cd~~~eft~hi~";
    string x = foo(input);
    cout << x << "\n";
    return 0;
}
Member Avatar for jencas

Yes, there are better ways! You do not need to start at the beginning every time, just use the iterator returned by erase():

string foo(string& inp)
{
    string::iterator it = inp.begin();
    for(; it != inp.end(); ++it)
    {
        if( *it == '~')
        {
            it = inp.erase(it); // because erase() invalidates iterator!!!
        }
    }
    return inp;
}

There is a much better way:
Just add a i-- in the body of the if statement;

for (int i = 0; i < inp.length(); i++)
	{
		if (inp[i] == '~')
		{
			inp.erase(i, 1);
			i--;
		}
	}

And it works like charm.
I dont know why are you using strlen instead of .length()

If you didn't understand why it worked by adding i--, call me back.

About the first post, it is a good programming practice to put the character code inside a const variable. Instead of hard-coding the ASCII code of the character, just put the constant. It is more elegant and is very useful if the character is not the wanted one (instead of changing all hard-coded values, just change the constant).

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.