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; }
问题原因及修复方案
两个核心问题
- 输入缓冲区残留换行符:当用户输入电话号码后按回车,
cin.get(letter)会读取所有字符,但最后那个换行符会留在输入缓冲区里。后续执行cin >> runLetter时,会直接读取这个换行符,而非等待用户输入,导致循环自动继续。 - 计数器未重置:
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
相关产品推荐
相关产品推荐

