Home > Net >  C Newbie: Why don't these nested loops work for this program?
C Newbie: Why don't these nested loops work for this program?

Time:11-08

I'm in the middle of taking an online C course, and I've been having issues with this homework problem. I tried reaching out to my professor twice, but he hasn't responded. I've sought out many solutions, but since I'm new in the course, many of the solutions involve using techniques I haven't learned yet (like character arrays.) I can get the conversion program to work, but I want the program to allow to process as many user inputs as the user wants.

When I run the program, the program accepts my first input that is 'y' or 'Y' to run the program. It then will ask for a string to convert to the telephone number. This works. However, I need the program to ask the user if they want to run the program again to convert another string to a telephone number or to terminate the program.

I put in another cin at the end of the first while loop to prompt for another input, but it gets skipped over everytime and keeps doing the while loop.

Question: Why is the last prompt to repeat the program get skipped every time I've run it? What am I missing? Here's the problem and what I've done so far:

Problem:

To make telephone numbers easier to remember, some companies use letters to show their telephone number. For example, using letters, the telephone number 438-5626 can be shown as GET LOAN.

In some cases, to make a telephone number meaningful, companies might use more than seven letters. For example, 225-5466 can be displayed as CALL HOME, which uses eight letters. Instructions

Write a program that prompts the user to enter a telephone number expressed in letters and outputs the corresponding telephone number in digits.

If the user enters more than seven letters, then process only the first seven letters.

Also output the - (hyphen) after the third digit.

Allow the user to use both uppercase and lowercase letters as well as spaces between words.

Moreover, your program should process as many telephone numbers as the user wants.

My code so far:

#include <iostream>

using namespace std;

int main()
{
    char letter, runLetter;
    int counter = 0;
    
    cout << "Enter Y/y to convert a telephone number from letters to digits" 
    << endl;
    cout << "Enter any other key to terminate the program." << endl;
    cin >> runLetter;


    while (runLetter == 'y' || runLetter == 'Y')
    {
        cout << "Enter in a telephone number as letters: " << endl;
        while (cin.get(letter) && counter < 7 ) 
        { 
            if (letter != ' ' && letter >= 'A' && letter <= 'z') 
            {
                counter  ;

                if (letter > 'Z') 
                {
                letter = (int)letter-32;
                }

                if (counter == 4)
                    cout << "-";

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

        cout << "To process another telephone number, enter Y/y" << endl;
        cout << "Enter any other key to terminate the program." << endl;
        cin >> runLetter;
    }

cout << "Goodbye. " << endl;
return 0;
}

Thanks in advance for any help. I know this might be an easy solution, but I've been tinkering with this program for a couple of days now.

Tried moving the last user prompt in and out of each if/else structure and different while loops. Not sure what I can do to make the program take a new input after the first iteration.

CodePudding user response:

A very good hint to your problem is the comment from @AlanBirtles. Also I know you are a beginner and you may not know about std::string but you should use it because you are learning C not C. in a nutshell, it is a C way of dealing with char arrays, also better than just that.

Here is your code with minimum changes to do what you are looking for. The main changes is the use of std::string, the use of std::getline and the definition of the counter inside the while loop.

#include <iostream>
#include <string>

using namespace std;

int main()
{
    char letter;
    std::string runLetter;
    std::string number;

    cout << "Enter Y/y to convert a telephone number from letters to digits"
        << endl;
    cout << "Enter any other key to terminate the program." << endl;
    std::getline( std::cin, runLetter);


    while (runLetter == "y" || runLetter == "Y")
    {        
        int counter = 0;
        cout << "Enter in a telephone number as letters: " << endl;
        std::getline(std::cin, number);
        for (int i = 0; i < number.size(); i  )
        {
            letter = number[i];
            if (counter < 7)
            if (letter != ' ' && letter >= 'A' && letter <= 'z')
            {
                counter  ;

                if (letter > 'Z')
                {
                    letter = (int)letter - 32;
                }

                if (counter == 4)
                    cout << "-";

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

        cout << endl;

        cout << "To process another telephone number, enter Y/y" << endl;
        cout << "Enter any other key to terminate the program." << endl;
        std::getline(std::cin, runLetter);
    }

    cout << "Goodbye. " << endl;
    return 0;
}   

CodePudding user response:

I found the following errors in your code:

  1. You do not reset the variable counter to 0 in the second loop iteration, so that counter has the value 7 in the entire second loop iteration, which causes the inner while loop not to be entered. This bug should be clearly visible when running your program line by line in a debugger while monitoring the values of all variables.

  2. You always read exactly 7 characters from the user per loop iteration, which is wrong. You should always read exactly one line per loop iteration. In other words, you should read until you find the newline character. You can ignore every character after the 7th letter, but you must still consume them from the input stream, otherwise they will be read in the next loop iteration(s), which you do not want. However, this does not mean that you can simply ignore everything after the 7th character, because the number of characters is not necessarily identical to the number of letters. As stated in the task description, the user should be allowed to enter spaces in the string. For example, if a 7 character string has one space character, then it only has 6 letters.

  • Related