输入2后C++程序卡在std::cin>>menu;后无法执行,求排查
问题排查:输入菜单2后程序卡顿无响应
问题现象
执行std::cin >> menu;输入数字2后,程序陷入卡顿,既不进入switch的case 2分支,也不执行cin后的输出语句;输入1、3、4或其他数字时运行完全正常。尝试过输入缓冲区清理方案,但未解决问题。
原代码
#include <iostream> #include <fstream> #include <unistd.h> struct jadwal { std::string Jurusan; int Jam; int Durasi; }; void daftarMenu() { std::cout << "aplikasi pertemuan" << std::endl; std::cout << "menu : " << std::endl; std::cout << "[1]. Input" << std::endl; std::cout << "[2]. Output" << std::endl; std::cout << "[3]. Hasil" << std::endl; std::cout << "[4]. Exit" << std::endl; } void inputJadwal() { int jumlah; jadwal jadwal[100]; std::cout << "Masukkan jumlah jadwal yang ingin ditambahkan : "; std::cin >> jumlah; std::ofstream file; file.open("file1.txt", std::ios::app); if(!file) { file.open("file1.txt", std::ios::trunc); }; for(int i = 0; i < jumlah; i++) { std::cin.ignore(); std::cout << "Jurusan : "; getline(std::cin, jadwal[i].Jurusan); file << jadwal[i].Jurusan; file << std::endl; std::cout << "Jam : "; std::cin >> jadwal[i].Jam; file << jadwal[i].Jam; file << std::endl; std::cout << "Durasi : "; std::cin >> jadwal[i].Durasi; file << jadwal[i].Durasi; file << std::endl; }; file.close(); std::cout << "Data berhasil di input, mengembalikan ke menu utama..." << std::endl; sleep(2); }; void outputJadwal() { jadwal jadwal[100]; std::ifstream file; file.open("file1.txt"); std::cout << "tes"; if(!file) { std::cout << "Tidak ada jadwal terdaftar" << std::endl; sleep(2); return; }; std::cout << "tes"; int index = 0; while(!file.eof()) { file >> jadwal[index].Jurusan; file >> jadwal[index].Jam; file >> jadwal[index].Durasi; index++; } int total = index + 1; for(int i = 0; i < total; i++) { std::cout << "Jurusan : " << jadwal[i].Jurusan; std::cout << "Jam " << jadwal[i].Jam; std::cout << "Durasi " << jadwal[i].Durasi; } file.close(); }; void hasilJadwal() { }; int main() { int menu; int jumlah; do{ daftarMenu(); std::cout << "Pilih : "; std::cin >> menu; std::cout << "you are choosing menu " << menu; switch(menu) { case 1: inputJadwal(); break; case 2: std::cout << "case 2 selected"; outputJadwal(); break; case 3: hasilJadwal(); break; case 4: std::cout << "Mengeliminasi program..."; return 0; default: std::cout << "Input tidak valid, mengembalikan ke menu utama..." << std::endl; sleep(2); break; } }while(true); return 0; }
尝试过的无效方案
if(std::cin.fail()) { std::cerr << "Error: Invalid input. Clearing input buffer and retrying..." << std::endl; std::cin.clear(); // 清除错误标志 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 丢弃无效输入 sleep(2); continue; // 重试循环 } std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
故障根源分析
- 输出缓冲区未刷新导致的调试误解:
outputJadwal()中的std::cout << "tes";没有立即输出,因为C++的std::cout默认是行缓冲模式,没有换行符时内容会暂存缓冲区,导致你误以为程序没进入case 2分支,实际上程序已经进入了outputJadwal函数。 - 致命的文件读取死循环:使用
while(!file.eof())是典型错误——当文件读取失败(比如字段格式不匹配、文件结束)时,file.eof()不会立即变为true,但流的错误标志会被设置,后续读取操作都会失败,循环会无限执行,导致程序卡顿。 - 输入输出格式不匹配:
inputJadwal()中用getline读取包含空格的专业名称并写入文件,但outputJadwal()中用file >> jadwal[index].Jurusan读取(该操作会在空格处停止),导致后续的Jam和Durasi读取失败,直接触发流错误标志,加剧死循环。
修复方案
1. 修复文件读取循环逻辑
替换错误的while(!file.eof()),改为直接检查读取操作是否成功:
int index = 0; // 只有当三个字段都读取成功时,才继续循环 while (file >> jadwal[index].Jurusan >> jadwal[index].Jam >> jadwal[index].Durasi) { index++; }
2. 修正数据总量统计逻辑
原代码中int total = index + 1;会多统计一条无效数据,直接使用index作为有效数据的总量:
int total = index; for(int i = 0; i < total; i++) { // 添加换行和分隔符,提升可读性 std::cout << "\nJurusan : " << jadwal[i].Jurusan; std::cout << " | Jam : " << jadwal[i].Jam; std::cout << " | Durasi : " << jadwal[i].Durasi; }
3. 强制刷新输出缓冲区
在调试输出后添加std::endl(自带刷新)或std::cout.flush(),确保内容及时显示:
std::cout << "tes" << std::endl;
4. 优化inputJadwal中的输入清理逻辑
避免多余的ignore吞掉有效输入,改为在读取jumlah后一次性清理换行符:
std::cin >> jumlah; // 清除输入缓冲区中剩余的换行符 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
(注意需要包含头文件<limits>以使用std::numeric_limits)
修复后完整代码
#include <iostream> #include <fstream> #include <unistd.h> #include <limits> // 新增头文件 struct jadwal { std::string Jurusan; int Jam; int Durasi; }; void daftarMenu() { std::cout << "aplikasi pertemuan" << std::endl; std::cout << "menu : " << std::endl; std::cout << "[1]. Input" << std::endl; std::cout << "[2]. Output" << std::endl; std::cout << "[3]. Hasil" << std::endl; std::cout << "[4]. Exit" << std::endl; } void inputJadwal() { int jumlah; jadwal jadwal[100]; std::cout << "Masukkan jumlah jadwal yang ingin ditambahkan : "; std::cin >> jumlah; std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 清理换行 std::ofstream file; file.open("file1.txt", std::ios::app); if(!file) { file.open("file1.txt", std::ios::trunc); }; for(int i = 0; i < jumlah; i++) { std::cout << "Jurusan : "; getline(std::cin, jadwal[i].Jurusan); file << jadwal[i].Jurusan << std::endl; std::cout << "Jam : "; std::cin >> jadwal[i].Jam; file << jadwal[i].Jam << std::endl; std::cout << "Durasi : "; std::cin >> jadwal[i].Durasi; file << jadwal[i].Durasi << std::endl; std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 清理Durasi后的换行 }; file.close(); std::cout << "Data berhasil di input, mengembalikan ke menu utama..." << std::endl; sleep(2); }; void outputJadwal() { jadwal jadwal[100]; std::ifstream file; file.open("file1.txt"); std::cout << "tes" << std::endl; // 添加endl刷新缓冲区 if(!file) { std::cout << "Tidak ada jadwal terdaftar" << std::endl; sleep(2); return; }; std::cout << "tes" << std::endl; // 添加endl刷新缓冲区 int index = 0; // 修复读取循环逻辑 while (file >> jadwal[index].Jurusan >> jadwal[index].Jam >> jadwal[index].Durasi) { index++; } int total = index; // 修正总量统计 for(int i = 0; i < total; i++) { std::cout << "\nJurusan : " << jadwal[i].Jurusan; std::cout << " | Jam : " << jadwal[i].Jam; std::cout << " | Durasi : " << jadwal[i].Durasi; } // 添加换行,避免后续菜单输出混乱 std::cout << std::endl; file.close(); }; void hasilJadwal() { }; int main() { int menu; do{ daftarMenu(); std::cout << "Pilih : "; std::cin >> menu; std::cout << "you are choosing menu " << menu << std::endl; // 添加endl刷新 switch(menu) { case 1: inputJadwal(); break; case 2: std::cout << "case 2 selected" << std::endl; // 添加endl刷新 outputJadwal(); break; case 3: hasilJadwal(); break; case 4: std::cout << "Mengeliminasi program..."; return 0; default: std::cout << "Input tidak valid, mengembalikan ke menu utama..." << std::endl; sleep(2); break; } }while(true); return 0; }
内容的提问来源于stack exchange,提问作者Ayodya Enhanayoan
相关产品推荐
相关产品推荐

