Telephone digit program

Hello, I need help with a homework assignment that I haven't bee bale to do for the past week.
I need to be able to do a telephone digit program where I can convert more than one letter at a time, have no more than 7 digits at a time, include a hyphen, allows both upper and lower case, and be able to repeat as many times as the user wants.
I feel that I am very close but very far away from how to properly do this. My professor does not help us with assignments and the information in our books is extremely limited.

I should be able to type something like "get loan" and have the output show as 438-5626, then have the program prompt the user to continue or end.

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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <iostream>
using namespace std;

int main()
{
    char letter;
    int counter = 0;

    cout << "This is a program to convert letters to their corresponding telephone digits." << "\nTo end the program enter '#'." << "\nEnter your letters: " << endl;
    
    do
    {
        cin >> letter;
        cout << endl;

        if (letter != ' ' && letter >= 'A' && letter <= 'z') 
        {
            counter++; //Adding a counter

            if (letter > 'Z') //Allowing conversion to lowercase
            {
                letter = (int)letter - 32;
            }

            if (counter == 4) //Adding a hyphen after the first three digits...does not work after first input
            {
                cout << "-";
            }

            switch (letter)
            {
            case 'A':
            case 'B':
            case 'C':
                cout << "2\n";
                break;
            case 'D':
            case 'E':
            case 'F':
                cout << "3\n";
                break;
            case 'G':
            case 'H':
            case 'I':
                cout << "4\n";
                break;
            case 'J':
            case 'K':
            case 'L':
                cout << "5\n";
                break;
            case 'M':
            case 'N':
            case 'O':
                cout << "6\n";
                break;
            case 'P':
            case 'Q':
            case 'R':
            case 'S':
                cout << "7\n";
                break;
            case 'T':
            case 'U':
            case 'V':
                cout << "8\n";
                break;
            case 'W':
            case 'X':
            case 'Y':
            case 'Z':
                cout << "9\n";
                break;
            default:
                cout << "Invalid input." << endl;
                break;
            }
            
            
        }
        cout << "\nEnter more letters if you wish to proceed." << "\nTo end the program enter '#'." << endl; //appears after every number...needs fix
    } 
    

    while (letter != '#');           
    return 0;
}
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
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <iostream>
#include <cctype>  // ::isalpha, ::toupper
#include <string>
#include <limits>

int main()
{
   char letter { };
   std::cout << "This is a program to convert letters to their corresponding telephone digits.\n"
      << "To end the input before 7 characters enter '#'.\n";

   do
   {
      int counter { };

      std::string number { };

      std::cout << "\nEnter your letters: ";

      do
      {
         std::cin >> letter;

         if (letter != '#' )
         {
            counter++;

            letter = ::toupper(letter);

            switch (letter)
            {
            case 'A': case 'B': case 'C':
               number += "2"; break;

            case 'D': case 'E': case 'F':
               number += "3"; break;

            case 'G': case 'H': case 'I':
               number += "4"; break;

            case 'J': case 'K': case 'L':
               number += "5"; break;

            case 'M': case 'N': case 'O':
               number += "6"; break;

            case 'P': case 'Q': case 'R': case 'S':
               number += "7"; break;

            case 'T': case 'U': case 'V':
               number += "8"; break;

            case 'W': case 'X': case 'Y': case 'Z':
               number += "9"; break;

            default:
               std::cout << "Invalid input.\n"; counter--;  break;
            }

            if (counter == 3) // adding a hyphen after the first three digits
            {
               number += "-";
            }
         }
      }
      while (letter != '#' && counter < 7);

      std::cout << '\n' << number << "\n\n";

      // clear out any left over characters
      std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

      std::cout << "Do you want to go again? ";
      std::cin >> letter;
      letter = ::toupper(letter);
   }
   while (letter != 'N');
}
This is a program to convert letters to their corresponding telephone digits.
To end the input before 7 characters enter '#'.

Enter your letters: g
@
Invalid input.
e
t
#

438-

Do you want to go again? y

Enter your letters: get#

438-

Do you want to go again? y

Enter your letters: get loan

438-5626

Do you want to go again? y

Enter your letters: getloan

438-5626

Do you want to go again? n

http://www.cplusplus.com/reference/cctype/
https://en.cppreference.com/w/cpp/io/basic_istream/ignore
I think that you would be better receiving all you letters - spaces included - in one go. So you could store your input in a string and input that with getline.

A fast and efficient way to code anything letter by letter is to use a map, in this case map<char,char>. Most of your outputs will be integer digits; however, that leaves you with the flexibility to do what you want with spaces or punctuation. And you can put all your output in a string by either replacement or adding a char at a time.
Thank you so much Furry Guy! Your code helped me a lot and I'm checking it over a bunch to make sure I understand it 100%.

Thank you, too, lastchance! I didn't think about doing it that way at all! I'm pretty new to coding so I will also look at what you said at try to implement it into my existing code to see how that works correctly!


Thank you both so very very much!!!
Hello rovert456,

A different approach, but keeping with what you started with:
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include <cctype>  // <--- For "std::tolower() and std::toupper()" + others.
#include <iostream>
#include <string>

using namespace std;

int main()
{
    char letter;
    int counter = 0;
    std::string phoneNumber;

    cout << "\n This is a program to convert letters to their corresponding telephone digits." << "\n To end the program enter '#'.\n\n";
    //<< "\n  Enter your letters (# To end) letter #" << counter + 1 << ": ";  // <--- Changed.

    do
    {
        cout << " Enter more letters if you wish to proceed. (# To end) letter " << counter + 1 << " :"; //appears after every number...needs fix
        cin >> letter;  // <--- Needs a prompt.

        letter = std::toupper(letter);

        //cout << endl;

        if (letter >= 'A' && letter <= 'Z')
        {
            counter++; //Adding a counter

            //if (letter > 'Z') //Allowing conversion to lowercase
            //{
            //    letter = (int)letter - 32;
            //}

            if (counter == 4) //Adding a hyphen after the first three digits...does not work after first input
            {
                phoneNumber+='-';
            }

            switch (letter)
            {
                case 'A':
                case 'B':
                case 'C':
                    phoneNumber += '2';
                    break;
                case 'D':
                case 'E':
                case 'F':
                    phoneNumber+='3';
                    break;
                case 'G':
                case 'H':
                case 'I':
                    cout << "4\n";
                    break;
                case 'J':
                case 'K':
                case 'L':
                    cout << "5\n";
                    break;
                case 'M':
                case 'N':
                case 'O':
                    cout << "6\n";
                    break;
                case 'P':
                case 'Q':
                case 'R':
                case 'S':
                    cout << "7\n";
                    break;
                case 'T':
                case 'U':
                case 'V':
                    cout << "8\n";
                    break;
                case 'W':
                case 'X':
                case 'Y':
                case 'Z':
                    cout << "9\n";
                    break;
                default:
                    cout << "\n S     Invalid input.\n\n";
                    break;
            }
        }
        else
        {
            cout << "\n E     Invalid input.\n\n";
        }

    } while (letter != '#' && counter < 7);

    std::cout << "\n\n The  number is: " << phoneNumber << '\n';

    return 0;
}


This is what I get for output:

 This is a program to convert letters to their corresponding telephone digits.
 To end the program enter '#'.

 Enter more letters if you wish to proceed. (# To end) letter 1 :a
 Enter more letters if you wish to proceed. (# To end) letter 2 :b
 Enter more letters if you wish to proceed. (# To end) letter 3 :c
 Enter more letters if you wish to proceed. (# To end) letter 4 :d
 Enter more letters if you wish to proceed. (# To end) letter 5 :e
 Enter more letters if you wish to proceed. (# To end) letter 6 :f
 Enter more letters if you wish to proceed. (# To end) letter 7 :a


 The  number is: 222-3332


The output could be done differently. More to the point of what it says.

I moved what is line 18 from the bottom of the do/while loop so it would not print an eighth line for input.

Also it is designed to take up to 7 letters before it quits unless you enter "#" early.

See what you think.

Andy
Assuming that a space in the input (for a '_' is mandatory), consider (without using map):

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
#include <iostream>
#include <string>
#include <string_view>
#include <limits>
#include <cctype>

int main()
{
	constexpr std::string_view digits = "22233344455566677778889999";
	constexpr char space {' '};

	static_assert(std::size(digits) == 26);

	for (std::string letters; (std::cout << "\nEnter letters to convert <CR to termiminate>: ") && std::getline(std::cin, letters) && !letters.empty(); ) {
		int hy {0};
		int alpha {0};

		for (auto& l : letters)
			if (l == space) {
				l = '_';
				++hy;
			} else
				if (std::isalpha(l)) {
					l = digits[std::toupper(l) - 'A'];
					++alpha;
				} else {
					alpha = 0;
					break;
				}

		if (hy != 1 || alpha < 1 || alpha > 7)
			std::cout << "Invalid input\n";
		else
			std::cout << letters << '\n';
	}
}

Last edited on
Thank you very much Andy! I appreciate the advice and I learned a lot from this!
Hello rovert456,

I forgot to mention your code if (letter != ' ' && letter >= 'A' && letter <= 'z') does not work.

First letter != ' '. Using formatted input, (cin >> letter), will not allow the input of a space. It will put the cursor on the next still waiting for a proper character.

letter >= 'A' && letter <= 'z'. Nice idea, but there are 6 characters betwiin "Z" and "a". Should you happen to enter 1 of them,([, \, ], ^, _, `), it would make that part of the if statement true. You do not want this.

I removed the if and else statements and let the switch handle everything.

After using the "std::toupper()" anything that did not catch a case statement ended up in the "default" case. I also changed the "default" case to:
1
2
3
4
default:
    cout << "\n      Invalid input.\n\n";
    counter--;
    break;


Andy
Thank you every one for the advice! Looking back on my code I realized how much of a mess it really was haha. Learned more from all of your help than this entire course so far!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <string>
#include <map>
using namespace std;

int main()
{
   const string digits = "22233344455566677778889999";
   map<char,char> code;
   for ( int i = 0; i < 26; i++ ) code['a'+i] = code['A'+i] = digits[i];

   string telephone;
   cout << "Enter letter string: ";   getline( cin, telephone );
   for ( char &c : telephone ) 
   {
      auto p = code.find( c );
      c = p == code.end() ? '-' : p->second;
   }
   cout << "Number " << telephone << '\n';
}


Enter letter string: GeT LoAn
Number 438-5626
Last edited on
@rovert456,

I used your original code as a "template" for what I wrote, so understanding the changes should be easier to digest. I could have used what lastchance suggested, but I feel too much new ideas thrown at you can be difficult to get a handle on.

Now, if I had been given this assignment without restrictions as to how to code it I would have mashed up something similar to what lastchance coded.
Topic archived. No new replies allowed.