You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++新手求助:嵌套循环致重复输入提示被跳过的原因

问题:多次转换电话号码时,程序跳过继续输入提示

我正在参加在线C++课程,完成作业时遇到问题。两次联系教授未获回复,找到的诸多解决方案用到了我尚未学习的技术(如字符数组)。我能实现字母转电话号码的功能,但希望程序支持用户多次输入。运行程序时,首次输入y/Y可正常执行转换,但最后询问是否继续的cin会被跳过,程序持续重复循环。

核心疑问: 为何重复程序的提示每次都会被跳过?我遗漏了什么?


作业要求

  • 提示用户输入字母形式的电话号码,输出对应数字号码;
  • 若输入超过7个字母,仅处理前7个;
  • 在第3位数字后输出连字符(-);
  • 支持大小写字母及单词间空格;
  • 支持用户处理多个电话号码。

当前代码

#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;
}

问题原因及修复方案

两个核心问题

  1. 输入缓冲区残留换行符:当用户输入电话号码后按回车,cin.get(letter)会读取所有字符,但最后那个换行符会留在输入缓冲区里。后续执行cin >> runLetter时,会直接读取这个换行符,而非等待用户输入,导致循环自动继续。
  2. 计数器未重置:counter变量在初始化时设为0,但第一次处理完7个有效字符后,它的值保持为7,后续循环中while (cin.get(letter) && counter <7)会直接跳过,同时缓冲区的换行符问题依然存在。

修复后的代码

#include <iostream>
#include <limits> // 用于清理输入缓冲区

using namespace std;

int main()
{
    char letter, runLetter;
    int counter; // 不在此处初始化,每次循环重置
    
    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')
    {
        counter = 0; // 每次处理新号码前重置计数器
        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 = static_cast<char>(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;
                }
            }
            // 收集够7个有效字符后,清理缓冲区并跳出循环
            if (counter >=7) {
                cin.ignore(numeric_limits<streamsize>::max(), '\n');
                break;
            }
        }
        // 处理输入不足7个有效字符的情况,清理缓冲区
        if (counter <7) {
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
        }
        
        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;
}

关键修改点

  • 每次循环开始时重置counter为0,确保新号码从0开始计数;
  • 使用cin.ignore(numeric_limits<streamsize>::max(), '\n')清理输入缓冲区的所有字符直到换行符,避免残留的换行符影响后续输入;
  • 把C风格的强制类型转换改成更安全的static_cast<char>;
  • 优化switch语句的格式,去掉多余的大括号,让代码更简洁。

内容的提问来源于stack exchange,提问作者rynosaurus745

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 17:01:18