Problem with string erase method

Feb 4, 2015 at 12:01am
I threw together a quick little program just to test/improve something I am currently working on. What this is suppose to do, when a user enters a phone number with illegal characters such as a space, (, -, etc. it will erase it from the string leaving only numbers 0-9. Every time I run it, it seems to erase values that I don't want to be erased. I tried numerous different ways, so this way might not seem the most efficient, but again I am only testing it right now.

Example of what program should do:

Enter phone number: (555) 555-5555
Return: 5555555555

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 #include<iostream>
#include<string>
using namespace std;

string isNumeric(string);

int main()
{
	string phoneNum;
	getline(cin, phoneNum);
	phoneNum = isNumeric(phoneNum);

	cout << phoneNum << endl;
	
	system("pause");
	return 0;
}

string isNumeric(string phoneNum)
{
	int cnt = 0;

	for (int i = 0; i < phoneNum.length(); ++i)
	{
		if (phoneNum[i] >= 0 && phoneNum[i] <= 9)
			cnt++;
		else
			phoneNum.erase (i, 1);		
	}
	return phoneNum;
}
Feb 4, 2015 at 12:11am
if (phoneNum[i] >= 0 && phoneNum[i] <= 9)You are comparing a char to integer values 0 and 9, you need to compare to char values '0' and '9'.
Feb 4, 2015 at 12:15am
Whoops, forgot about that....Brain fart, shoulda compared it to original, thanks though!!
Feb 4, 2015 at 12:20am
The line 25. You compare characters to numbers. A char does have a numeric value, but a '7' is not 7.
Use http://www.cplusplus.com/reference/cctype/isdigit/


What is the purpose of cnt?


You could use std::count_if and std::copy_if from http://www.cplusplus.com/reference/algorithm/
Feb 4, 2015 at 12:30am
I am experimenting, as I said in my post, and I could use a counter for various things. Also ran into another problem:

For the most part it seems to work good removing the illegal charcters, but if i put

555gffd555fgs5555 (For testing purposes)
It will not fully remove all the letters.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include<iostream>
#include<string>
using namespace std;

string isNumeric(string);
string format(string);

int main()
{
	string phoneNum;

	do
	{
		cout << "Enter your 10 digit phone number: ";
		getline(cin, phoneNum);
		phoneNum = isNumeric(phoneNum);

		if (phoneNum.length() != 10)
		{
			cout << "Make sure you enter a 10 digit phone number!" << endl;
		}
	} while (phoneNum.length() != 10);

	phoneNum = format(phoneNum);
	cout << "Your number: " <<phoneNum << endl;
	
	system("pause");
	return 0;
}

string isNumeric(string phoneNum)
{
	for (int i = 0; i < phoneNum.length(); i++)
	{
		if (phoneNum[i] < '0' || phoneNum[i] > '9')
			phoneNum.erase(i, 1);
	}
	return phoneNum;
}

string format(string phoneNum)
{
	string area, verification, numbers;

	area = phoneNum.substr(0, 3);
	verification = phoneNum.substr(3, 3);
	numbers = phoneNum.substr(6, 4);

	return '(' + area + ')' + ' ' + verification + '-' + numbers;
}
Feb 4, 2015 at 1:03am
You're over-complicating the checks. With newer functionality (2011+) you can do this sort of stuff quite easily. Get in to the idea of telling the compiler "what to do" vs "how to do it".

e.g
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

bool is_ok(char c) {
  return !isdigit(c);
}

int main ()
{
    string phone_number;

    cout << "Enter phone number: ";
    getline(cin, phone_number);

    cout << "Original Phone number: " << phone_number << endl;
    phone_number.erase(std::remove_if(phone_number.begin(), phone_number.end(), is_ok), phone_number.end());
    cout << "Phone number after: " << phone_number << endl;

    return 0;
}


Output is:

Enter phone number: (123) 4567 891011
Original Phone number: (123) 4567 891011
Phone number after: 1234567891011


To even simplify this further using a lamba expression it'd be:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

int main ()
{
    string phone_number;

    cout << "Enter phone number: ";
    getline(cin, phone_number);

    cout << "Original Phone number: " << phone_number << endl;
    phone_number.erase(std::remove_if(phone_number.begin(), phone_number.end(),
        [](char x) { return !isdigit(x);}),
        phone_number.end());
    cout << "Phone number after: " << phone_number << endl;

    return 0;
}
Feb 4, 2015 at 1:35am
Yeah, but you see I can only use things that I have actually learned in class so half of that code is new to me and have no idea whats going on, only second semester doing computer science.

EDIT: Would there be a possible solution to fix it the way I had it on my last post w/o the use of vectors or a lamba expression?
Last edited on Feb 4, 2015 at 1:43am
Feb 4, 2015 at 4:43am
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <string>
#include <cctype>

std::string filter( std::string phone_number )
{
    std::string filtered_result ;

    // http://www.stroustrup.com/C++11FAQ.html#for
    for( char c : phone_number )
        if( std::isdigit(c) ) filtered_result += c ;

    return filtered_result ;
}

std::string filter_2( std::string phone_number ) // legacy C++
{
    std::string filtered_result ;

    for( std::size_t i = 0 ; i < phone_number.size() ; ++i )
        if( std::isdigit( phone_number[i] ) ) filtered_result += phone_number[i] ;

    return filtered_result ;
}
Topic archived. No new replies allowed.