Keypad Translation Solution: Program for Correctly Mapping Keys to Letters

  • Comp Sci
  • Thread starter whysoserious2
  • Start date
  • Tags
    Translation
In summary, the code is trying to read in a sequence of numbers, but is getting errors on line 17 when it tries to test whether the i'th character is '222'. The code needs to scan each character in the sequence one by one, and enter a space if the digit is '0'.
  • #1
whysoserious2
10
1
Homework Statement
Write a program to read a sequence of non-empty keystrokes and output the translated message and the number of characters typed. Note that the "space" should be counted as a character in the output.
Relevant Equations
Assume that the input message will not start with 0 and the length of the input message always consists of 17 digits.
Been trying to work this out for a while now but struggling to come up with a program that reads all of the samples. Based on the keypad, I should be receiving an "a" when I press "2" once. However, when I put in the code "222", I still get "a" instead of "c". I've attached the codes I put in and would appreciate any help I can get!

C++:
#include <iostream>
#include <string>
using namespace std;

int main( )
{
    int i;
    string message;
    cout << "Please enter the  message: ";
    cin >> message;
    cout << endl;

    for (i = 0; i < message.size(); i++)
    {
        if (message[i] == '#')  cout << '#';
        if (message[i] == '1')  cout << ' ';
        if (message[i] == '222')  cout << 'C';
        else if (message[i] == '22')  cout << 'B';
        else if (message[i] == '2')  cout << 'A';

        if (message[i] == '444')  cout << 'I';
        else if (message[i] == '44')  cout << 'H';
        else if (message[i] == '4')  cout << 'G';
    }

    cout << endl;
    return  0;
}
 

Attachments

  • Assignment.pdf
    191.7 KB · Views: 332
  • Code.png
    Code.png
    47.9 KB · Views: 158
Last edited by a moderator:
Physics news on Phys.org
  • #2
Welcome to PF. :smile:

Please post your code in the forum window using the following tags (leave out the spaces to make them real tags:

[ code ]
<your code here>
[ /code ]

That will make it a lot easier for us to help. Thanks.
 
  • #3
berkeman said:
Welcome to PF. :smile:

Please post your code in the forum window using the following tags (leave out the spaces to make them real tags:

[ code ]
<your code here>
[ /code ]

That will make it a lot easier for us to help. Thanks.
Thank you! Just put in the codes.
 
  • Like
Likes berkeman
  • #4
On line 17 you test whether the i'th character of the string is '222'. How many characters are there in '222'? How many characters are there in the i'th character of a string?
 
Last edited by a moderator:
  • Like
Likes sysprog and berkeman
  • #5
pbuk said:
On line 17 you test whether the i'th character of the string is '222'. How many characters are there in '222'? How many characters are there in the i'th character of a string?
And similar problems on lines 18, 21, and 22.

To the OP: Instead of looking for sequences like 222, 22, 444, 44, etc. in that order, start from the first digit, and see if the next digit is the same, and if the third digit is also the same. You'll need a nested if else block for each digit 1 through 9.
 
  • Like
Likes sysprog
  • #6
Mark44 said:
And similar problems on lines 18, 21, and 22.

To the OP: Instead of looking for sequences like 222, 22, 444, 44, etc. in that order, start from the first digit, and see if the next digit is the same, and if the third digit is also the same. You'll need a nested if else block for each digit 1 through 9.
Thanks for the guidance! I understand how to do a nested if else block, but I'm not quite sure what to write as the conditions or how to scan each character in the sequence one by one in a loop.
 
  • #7
whysoserious2 said:
I'm not quite sure what to write as the conditions or how to scan each character in the sequence one by one in a loop.
Please look up the increment operator in your textbook, or read here: (fnal.gov) C++ Syntax: Increment: ++
  1. If ++ precedes the variable, e.g. ++counter, the value returned is the value in counter after it has been incremented.
  2. If ++ follows the variable, e.g. counter++, the value returned is the value in counter before it has been incremented.
Usage Notes
Its best not to overuse the operator, and never apply it twice to the same variable in the same statement, for example:-
my_int[index++] = index++;
is ambiguous as C++ is allowed to evaluate either ++ first.
 
  • #8
Scanning the characters is simple -- message[ i] gives you the character at index i in the string. The conditions are more complicated.

I have most of a solution -- all but the '9' digit, which can translate into W, X, Y, or Z. All the other digits, from '2' to '8' translate into one of three digits.

Here's what I did. I looked at each digit in the string, outputting a space if the digit is '0', and doing nothing if the digit is '1'. Then I used a switch statement for the digits '2' through '8' (again, I haven't implemented anything for a '9' digit). For each of these digits, I look ahead two digits in the string, to see if I have a string of 3 repeated digits. If so, I know that I need to out put the third character in the appropriate sequence ABC, DEF, and so on, and I increment the index in the string by 2.
If I don't have a string of 3 repeated digits, I look one digit ahead to see if I have a pair of repeated digits. If so, I output the 2nd character in the appropriate sequence ABC, DEF, and so on, and I increment the index in the string by 1.
If both of the conditions above have failed, I simply output the first character in the appropriate sequence.

The tricky part is figuring out from the digit in the string which is the appropriate sequence; i.e., the proper mapping between '2' and ABC, between '3' and DEF, between '4' and GHI, and so on.
 
Last edited:
  • #9
For 2 through 8, you could test for no repetition, 1 rep, 2 or more reps, to establish which of the 1st, 2nd, or 3rd letters was to be substituted for 1, 2, or 3 or more characters of the input string, and then get the letter from a 3x8 character array ##-## and that pesky 9 is left as an exercise for the reader . . .
 
Last edited:
  • #10
Mark44 said:
I have most of a solution -- all but the '9' digit, which can translate into W, X, Y, or Z.
Correction, the '7' digit also is a special case, as it can translate into P, Q, R or S.
 
  • #11
I also neglected to account for the 4 possible letters for 7 ##-## I'll reply again later ##-## have to go for now.
 
  • #12
sysprog said:
I also neglected to account for the 4 possible letters for 7 ##-## I'll reply again later ##-## have to go for now.
Thank you all so much for your feedback! I am able to understand the hints given but have difficulty putting all the theories into action. I am wondering if I need to be using a function that I have not learned yet. Below are the ones that our class has gone over for now:
  • if-then
  • if-then-else
  • switch statement
  • ASCII code
  • loops
  • variables:
    • int
    • string
    • char
    • double
    • bool
Can anyone kindly point me in the direction of which function to use if it is not in the ones listed above?
 
Last edited:
  • #13
whysoserious2 said:
Thank you all so much for your feedback! I am able to understand the hints given but have difficulty putting all the theories into action. I am wondering if I need to be using a function that I have not learned yet. Below are the ones that our class has gone over for now:
  • if-then
  • if-then-else
  • switch statement
  • ASCII code
  • loops
  • variables:
    • int
    • string
    • char
    • double
    • bool
Can anyone kindly point me in the direction of which function to use if it is not in the ones listed above?
None of these are functions. if, if - else (there is no "then" keyword in C, C++, C#, Java, etc.), and switch...case are keywords that represent control structures for making decisions. The repetition or looping control structures are for, while, and do ... while.

In my code I have a for loop that iterates over the characters in the message string, and in the body of the loop I have a switch statement that takes different actions depending on which character has been encountered in the message string.

The only keyword I used in my code that you didn't list is break, which is used for two different purposes:
  • In a switch statement, break causes the code to exit the switch statement.
  • In a loop, break causes the code to exit the loop.
I imagine you've already encountered break statements when you were learning about loops or the switch statement.

The reason I used a switch statement was so that I didn't have to have a lot of repeated code consisting of repeated if or if .. else statements. It's possible to write the program without switch, but it will be longer.

I also used the ASCII codes of the number digits to get a correspondence between characters such as '2' and so on and number values. The digit characters have ASCII codes between 48 ('0') and 57 ('9').
 
  • #14
Mark44 said:
None of these are functions. if, if - else (there is no "then" keyword in C, C++, C#, Java, etc.), and switch...case are keywords that represent control structures for making decisions. The repetition or looping control structures are for, while, and do ... while.

In my code I have a for loop that iterates over the characters in the message string, and in the body of the loop I have a switch statement that takes different actions depending on which character has been encountered in the message string.

The only keyword I used in my code that you didn't list is break, which is used for two different purposes:
  • In a switch statement, break causes the code to exit the switch statement.
  • In a loop, break causes the code to exit the loop.
I imagine you've already encountered break statements when you were learning about loops or the switch statement.

The reason I used a switch statement was so that I didn't have to have a lot of repeated code consisting of repeated if or if .. else statements. It's possible to write the program without switch, but it will be longer.

I also used the ASCII codes of the number digits to get a correspondence between characters such as '2' and so on and number values. The digit characters have ASCII codes between 48 ('0') and 57 ('9').
I tried to implement some of the new hints you all have given but am still having trouble. When I type in three "2's" I get three "A's" instead of a C.
 

Attachments

  • Code2.png
    Code2.png
    26.1 KB · Views: 155
  • #15
whysoserious2 said:
I tried to implement some of the new hints you all have given but am still having trouble. When I type in three "2's" I get three "A's" instead of a C.
That's because your code doesn't take into account that a digit can be repeated. Your code just looks at a digit in the string, and displays the first of the three characters for that digit. For the digits '2' through '6' and '8', your code needs to look two digits ahead to see if the current digit is by itself, or is followed by the same digit, or is followed by two more of the same digits. IOW, it needs to be able to handle, say, "2xy", "22x", and "222", where x and y are digits other than the current one at index i.
The code also needs to handle a "pause" digit, '1'. Your code currently doesn't handle '1' at all. So in addition to the above, it needs to handle "21" and "221".
Do you understand the purpose of the '1' digit?

The '7' and '9' digits are a bit more complicated, since each of these can represent four different characters.

In addition, if you post code, please post it as text rather than as a screen shot, and use code tags as in the following.

[code=cpp]
C++:
int main()
{
    std::string message;
    cout << "Please enter the  message: ";
    cin >> message;
    cout << endl;
    unsigned msgSize = message.size();
    // etc.
[/code]

After you post the code, the code tags won't show up -- I've done something to them to keep them from being rendered in the browser.
 
  • #16
Mark44 said:
That's because your code doesn't take into account that a digit can be repeated. Your code just looks at a digit in the string, and displays the first of the three characters for that digit. For the digits '2' through '6' and '8', your code needs to look two digits ahead to see if the current digit is by itself, or is followed by the same digit, or is followed by two more of the same digits. IOW, it needs to be able to handle, say, "2xy", "22x", and "222", where x and y are digits other than the current one at index i.
The code also needs to handle a "pause" digit, '1'. Your code currently doesn't handle '1' at all. So in addition to the above, it needs to handle "21" and "221".
Do you understand the purpose of the '1' digit?

The '7' and '9' digits are a bit more complicated, since each of these can represent four different characters.

In addition, if you post code, please post it as text rather than as a screen shot, and use code tags as in the following.

[code=cpp]
C++:
int main()
{
    std::string message;
    cout << "Please enter the  message: ";
    cin >> message;
    cout << endl;
    unsigned msgSize = message.size();
    // etc.
[/code]

After you post the code, the code tags won't show up -- I've done something to them to keep them from being rendered in the browser.
Here's my latest attempt. I managed to successfully get a "c" but is somehow having trouble with producing "b's" using the same logic. For example, when I enter "222", my output says "CB". When I enter "33322," I get FFCB.

Code:
string message; 
string output; 
cout << "Please enter the message: ";
cin >> message; 

for (i = 0; i < message.size(); i++) 
{
          if (message[i] == '2')
              if ((message[i] = message[i + 1]) && (message[i + 1] = message[i + 2]))
                   printf("C"); 
              else if (message[i] = message[i++])
                   printf("B"); 

          if (message[i] == '3')
              if ((message[i] = message[i + 1]) && (message[i + 1] = message[i + 2]))
                  printf("F"); 
              else if (message[i] = message[i++])
                  printf("E"); 

          else 
               switch (message[i]) {
                  case 48: printf(" "); break; 
                  case 50: printf("A"); break;
                  case 51: printf("D"); break;  
                  case 52: printf("G"); break;
                  case 53: printf("J"); break;  
                  case 54: printf("M"); break;
                  case 55: printf("P"); break;  
                  case 56: printf("T"); break;
                  case 57: printf("W"); break;  
               }

}
 
  • #17
You have several logic errors in your code.
C++:
for (i = 0; i < message.size(); i++) 
{
          if (message[i] == '2')
              if ((message[i] = message[i + 1]) && (message[i + 1] = message[i + 2]))
                   printf("C"); 
          <snip>
In the nested if...else statements, you're not checking whether message[ i] happens to be equal to message[ i+1] -- you are actually assigning values to the variables on the left. You have the same logic errors in all of the nested if ... else statements.
 
  • #18
Mark44 said:
You have several logic errors in your code.
C++:
for (i = 0; i < message.size(); i++)
{
          if (message[i] == '2')
              if ((message[i] = message[i + 1]) && (message[i + 1] = message[i + 2]))
                   printf("C");
          <snip>
In the nested if...else statements, you're not checking whether message[ i] happens to be equal to message[ i+1] -- you are actually assigning values to the variables on the left. You have the same logic errors in all of the nested if ... else statements.
I recognize the issue you mentioned. I think my biggest issue is that I don’t know how to resolve what you pointed out (e.g., how to check whether message[ i] happens to be equal to [i+1]) because I’ve not learned this yet, but our professor is expecting us to complete this question.
 
  • #19
whysoserious2 said:
I recognize the issue you mentioned. I think my biggest issue is that I don’t know how to resolve what you pointed out (e.g., how to check whether message[ i] happens to be equal to [i+1]) because I’ve not learned this yet, but our professor is expecting us to complete this question.
I think you have learned it already -- use == instead of = in the comparisons. You used the correct operator in if (message[ i] == '2') and if (message[ i] == '3').
 
  • #20
Mark44 said:
I think you have learned it already -- use == instead of = in the comparisons. You used the correct operator in if (message[ i] == '2') and if (message[ i] == '3').
With the below code, I still get CBE when entering 22233.
Code:
for (i = 0; i < message.size(); i++)
{
          if (message == '2')
             if ((message[i] == message[i + 1]) && (message[i + 1] == message[i + 2]))
                 printf("C");
          else if (message[i] == message[i++])
                 printf("B");
 
Last edited:
  • #21
In the code in post 8, line 4, the first comparison is message == message[ i + 1]. The expression on the left should be message[ i], not message.
 
  • #22
Mark44 said:
In the code in post 8, line 4, the first comparison is message == message[ i + 1]. The expression on the left should be message[ i], not message.
That was a typo on my end. Even with message, I still receive CBE upon entering 22233.
 
  • #23
For repeated digits, such as 222, you need to account for the fact that although you're reading 3 digits, you're going to print only 1 letter.

In the code below, the first embedded if statement detects a situation where you have 222. Before printing C, the index in the string is moved to the final 2 digit. In the next iteration of the loop, the index will be incremented to the first character after the 222 sequence.

The second embedded if statement detects a situation where you have 22n, with n being some digit other than 2. Before printing B, the index is moved to the second 2 digit, and in the next iteration of the for loop, the index will be incremented to the first character after 22.

C++:
for (i = 0; i < message.size(); i++)
{
          if (message == '2')
             if ((message[ i] == message[i + 1]) && (message[i + 1] == message[i + 2])) {
                 i += 2;                         // Move index to 3rd character in repeated sequence.
                 printf("C");
             }
             else if (message[ i] == message[i++]) {
                 i += 1;                         // Move index to 2nd character in repeated sequence
                 printf("B");
             }
On an unrelated note, when you write your code in a code block (as I have done), be careful with i as an array index. If you write xxx[ i], without a space between the left bracket and i, a browser will interpret this as the start of a BBCode italics code, and will not display the bracketed text. To counter this, I add a space between the left bracket and i -- like so xxx[ i].
 
  • #24
Mark44 said:
For repeated digits, such as 222, you need to account for the fact that although you're reading 3 digits, you're going to print only 1 letter.

In the code below, the first embedded if statement detects a situation where you have 222. Before printing C, the index in the string is moved to the final 2 digit. In the next iteration of the loop, the index will be incremented to the first character after the 222 sequence.

The second embedded if statement detects a situation where you have 22n, with n being some digit other than 2. Before printing B, the index is moved to the second 2 digit, and in the next iteration of the for loop, the index will be incremented to the first character after 22.

C++:
for (i = 0; i < message.size(); i++)
{
          if (message == '2')
             if ((message[ i] == message[i + 1]) && (message[i + 1] == message[i + 2])) {
                 i += 2;                         // Move index to 3rd character in repeated sequence.
                 printf("C");
             }
             else if (message[ i] == message[i++]) {
                 i += 1;                         // Move index to 2nd character in repeated sequence
                 printf("B");
             }
On an unrelated note, when you write your code in a code block (as I have done), be careful with i as an array index. If you write xxx[ i], without a space between the left bracket and i, a browser will interpret this as the start of a BBCode italics code, and will not display the bracketed text. To counter this, I add a space between the left bracket and i -- like so xxx[ i].
Thanks so much! I was able to resolve the issues by adding i += 2 and i += 1. If it’s not too much trouble, can you explain what that is because I don’t think I’ve ever learned it.

Also, thank you for pointing out the need to add a space between the left bracket and i. Although it didn’t make a difference for me, it’s good to know for future reference.
 
  • #25
whysoserious2 said:
Thanks so much! I was able to resolve the issues by adding i += 2 and i += 1. If it’s not too much trouble, can you explain what that is because I don’t think I’ve ever learned it.
This is one of several compound assignment operators. i += 2; has the same effect as writing i = i + 2; . And similar for i +=1; .

All of the arithmetic operators (+ - * / %) and the bitwise operators have compound forms.
 

FAQ: Keypad Translation Solution: Program for Correctly Mapping Keys to Letters

What is a keypad translation solution?

A keypad translation solution is a program that maps keys on a keypad to corresponding letters, allowing users to input text using a keypad instead of a full keyboard.

Why is a keypad translation solution needed?

A keypad translation solution is needed because many devices, such as cell phones and calculators, have keypads instead of full keyboards. This solution allows users to input text using the limited keys available on a keypad.

How does a keypad translation solution work?

A keypad translation solution works by assigning each key on a keypad to a specific letter. For example, the number 2 key may be mapped to the letters A, B, and C. When a user presses the number 2 key, the program recognizes which letter is associated with that key and inputs it into the text.

Can a keypad translation solution be customized?

Yes, a keypad translation solution can be customized to fit the needs of different devices or languages. The key-to-letter mappings can be adjusted to accommodate different layouts or characters.

Are there any limitations to a keypad translation solution?

One limitation of a keypad translation solution is that it can be difficult to input special characters or punctuation marks that are not mapped to a specific key. Additionally, if the key-to-letter mappings are not intuitive, it may be challenging for users to remember which key corresponds to which letter.

Similar threads

Replies
3
Views
988
Replies
2
Views
3K
Replies
8
Views
1K
Replies
7
Views
1K
Replies
2
Views
2K
Replies
3
Views
1K
Replies
6
Views
3K
Back
Top