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

输入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');

故障根源分析

  1. 输出缓冲区未刷新导致的调试误解:outputJadwal()中的std::cout << "tes";没有立即输出,因为C++的std::cout默认是行缓冲模式,没有换行符时内容会暂存缓冲区,导致你误以为程序没进入case 2分支,实际上程序已经进入了outputJadwal函数。
  2. 致命的文件读取死循环:使用while(!file.eof())是典型错误——当文件读取失败(比如字段格式不匹配、文件结束)时,file.eof()不会立即变为true,但流的错误标志会被设置,后续读取操作都会失败,循环会无限执行,导致程序卡顿。
  3. 输入输出格式不匹配: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 20:07:33