Problem with string erase method

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;
}
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'.
Whoops, forgot about that....Brain fart, shoulda compared it to original, thanks though!!
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/
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;
}
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;
}
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
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.