Converting Letters to Their corresponding T9 Numbers

May 5, 2020 at 3:51am
I'm messing with this program that should prompt the user to enter a telephone number expressed in letters and output the corresponding telephone number in digits. I'm getting so close but I can't figure out how to deal with the user input being a space. How can I get the loop to skip over any spaces that the user inputs?

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
  #include <iostream>
#include <iomanip>
#include <string>

using namespace std;

int main()
{
    int num, digit;
    char letter[8];
    string phoneLetters;
    string phoneNum;

    cout << "Program that converts letters into a phone number, " <<
    "\nbased on the T9 numeric keypad." << endl << endl;

    cout << "Enter a string to be converted: " << flush;

    cin >> phoneLetters;

    for (int i = 0; i < 7; i++) {
        letter[i] = phoneLetters[i];

        if (static_cast<int>(letter[i]) >= 97 && static_cast<int>(letter[i]) <= 122) {
            letter[i] = static_cast<int>(letter[i]) - 32;
        }



        digit = ((letter[i] - 65) / 3) + 2;

        if (digit >= 9 || digit <= 0) {
            digit = 0;
        }


        if (letter[i] == letter[3]) {
            cout << "-";
        }

        cout << digit;
    }

    return 0;
}
May 5, 2020 at 4:41am
> if (static_cast<int>(letter[i]) >= 97
Use tolower()
https://www.cplusplus.com/reference/cctype/tolower/

How can I get the loop to skip over any spaces that the user inputs?
Maybe
if ( letters[i] == ' ' )

There seems to be no real point to letters[i], you may as well just have
currentletter = phoneLetters[i];
May 5, 2020 at 3:03pm
I'll check it out and clean it up, thanks!
May 5, 2020 at 6:50pm
I still can't get the for loop to skip over a space without completely jumping out of the loop. This is what I have now.
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
#include <iostream>
#include <iomanip>
#include <string>
#include <ctype.h>

using namespace std;

int main()
{
    int digit;
    char letter, cLetter;
    string phoneLetters;

    cout << "Program that converts letters into a phone number, " <<
    "\nbased on the T9 numeric keypad." << endl << endl;

    cout << "Enter a string to be converted: " << flush;

    cin >> phoneLetters;

    for (int i = 0; i < 8; i++)
        {
        letter = phoneLetters[i];

        if (letter == ' ') {
            cout << "";
            continue;
        }

        while (isalpha(letter))
        {
            if (islower(letter))
                {
                letter = toupper(letter);
            }
            digit = ((letter - 65) / 3) + 2;

            if (i == 3) {
                cout << "-";
            }

            cout << digit;
            break;
        }

    }

    return 0;
}
Last edited on May 5, 2020 at 6:52pm
May 5, 2020 at 7:54pm
> cin >> phoneLetters;
You need to use getline() if you want to read a whole line, including spaces.

1
2
3
4
while (isalpha(letter)) {
  //..
  break;
}

You may as well just make this an if statement and get rid of the break.
It's the same thing.
May 5, 2020 at 8:20pm
I GOT IT! It could still use some work, but I'm getting there, here's what I did...

Edit: Nevermind, it sort of works, but it will repeat one number after the space -.-
and if I take out the i-- then the program wont add a hyphen correctly.

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
    getline(cin, phoneLetters);


    for (int i = 0; i < 7; i++)
        {
        letter = phoneLetters[i];

        if (letter == ' ')
        {
            i++;
            letter = phoneLetters[i];
            i--;
        }

        while (isalpha(letter))
        {
            if (islower(letter))
                {
                letter = toupper(letter);
            }
            digit = ((letter - 65) / 3) + 2;

            if (i == 3) {
                cout << "-";
            }

            cout << digit;
            break;
        }

    }

    return 0;
}

Last edited on May 5, 2020 at 8:25pm
May 5, 2020 at 10:56pm
Hello GamerAid,

Quick question. Do you need the array char letter[8];? Do you have to use this?

Andy
May 5, 2020 at 11:07pm
No I took that out
May 6, 2020 at 1:18am
Hello GamerAid,

Just a quick note: your code:
1
2
3
cout << "Enter a string to be converted: " << flush;

cin >> phoneLetters;

The "flush" although better than "endl" is not needed because the following "cin" will "flush" the output buffer before it takes your input. Not 100% sure, but I believe that the "input " and "output" buffers use the same memory.

In a sense you are making more work for your-self than you need to when you can use what you have.

I have included the whole program so you can see the comments I have put in.
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
51
52
53
54
55
56
57
58
59
60
61
62
#include <cctype>
#include <iostream>
//#include <iomanip>  // <--- Not needed or used in this program. Will not hurt if you leave it.
#include <limits>  // <--- Added for the end of "main", but may not be needed.
#include <string>

using namespace std;

int main()
{
	int digit;
	//char letter[8]{};  // <--- Not needed.
	//string phoneNum;  // <--- Not needed or used.

	// <--- Change comments of any two lines to test different letters.
	//string phoneLetters{"abc defg"};
	string phoneLetters{ "hijklmn" };
	//string phoneLetters{ "opq rstu" };
	//string phoneLetters{ "vwx-yzab" };

	//std::string phoneLetters;  // <--- Original definition. Use when finished testing.

	cout << "Program that converts letters into a phone number, " <<
		"\nbased on the T9 numeric keypad.\n\n";

	cout << "Enter a string to be converted: " << phoneLetters << "\n\n";  // <--- Changed for testing. Remone the ("\n\n")s when finished.

	//std::getline(std::cin, phoneLetters); // <--- Commented for testing.

	for (size_t i = 0; i < phoneLetters.size(); i++)
	{
		phoneLetters[i] = std::toupper(phoneLetters[i]);

		if (isspace(phoneLetters[i]) || phoneLetters[i] == '-')
		{
			std::cout << '-';

			continue;
		}

		digit = ((phoneLetters[i] - 'A') / 3) + 2;

		if ((phoneLetters[i] == 'S' || phoneLetters[i] == 'V' || phoneLetters[i] == 'Y' || phoneLetters[i] == 'Z'))
		{
			digit--;
		}

		if (i == 3)
			cout << "-";

		cout << digit;
	}

	// Use or delete your choice.
	// A fair C++ replacement for "system("pause")". Or a way to pause the program.
	// The next line may not be needed. If you have to press enter to see the prompt it is not needed.
	//std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.
	std::cout << "\n\n Press Enter to continue: ";
	std::cin.get();

	return 0;  // <--- Not required, but makes a good break point for testing.
}

In line 30 the ".size()" function returns a "size_t", an alias for "unsigned int". It helps, and avoids the warning of a type difference, when the types match. Using this is better than the "7" you started with because that size of the string could be 7 or 8 or maybe more. This will check the whole string no matter what the size is.

Line 32 changes the string before you start processing. Should that element be an upper case letter or something other than a lower case letter nothing is changed.

In line 43 these are the only 4 letters that become a problem based on the T9 key pad.

The rest of the program works as is.

Andy
May 6, 2020 at 2:14pm
Wow, thanks a bunch mate. I'll save this in my projects folder for reference.

I know I was making a big mess, but I was trying pretty hard because I need the practice. I'm so bad at this right now, but we gotta start somewhere :)

Lots of great tips in there! Thanks again Andy, huge help.
Topic archived. No new replies allowed.