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

C++调用display函数后循环无限执行 scanf无法接收输入问题

问题根因
  • 核心错误为display_d函数末尾执行了fclose(stdin):stdin是C标准库预设的全局标准输入流,对应程序的键盘输入通道,手动关闭该流后,后续scanf尝试从已关闭的流读取数据会直接调用失败,既不会读取输入也不会修改变量n的值,n会始终保持为上次输入的2,循环判断条件n != 0永久成立,程序进入死循环。
  • 次要问题:fopen打开文件后未做判空处理,若文件不存在或权限不足导致打开失败,fptr为NULL,后续fread会触发空指针访问,直接导致程序崩溃。
  • 潜在问题:主菜单case 2中调用的函数名为display(),但你给出的实现函数名为display_d(),需确认二者是否为笔误,避免函数调用不匹配的问题。
修复方案
  1. 首先删除display_d函数中完全错误的fclose(stdin);语句,改为关闭你自行打开的文件指针fptr。
  2. 补充文件打开失败的判空逻辑,避免空指针访问。
  3. 可选优化:为scanf增加返回值校验,处理用户输入非数字的异常场景,避免非法输入导致的死循环。

修正后的display_d函数代码如下:

void display_d(){
    point c1;
    FILE *fptr;
    fptr = fopen("company_det.txt","r");
    // 新增文件打开失败判断
    if(fptr == NULL){
        printf("公司信息文件打开失败,请检查文件是否存在\n");
        return;
    }
    while(fread(&c1,sizeof(point),1,fptr)){
        printf("\n%s %s %d\n",c1.company_name,c1.bla.date,c1.bla.price);
    }
    // 关闭自行打开的文件指针
    fclose(fptr);
}

添加了输入校验的主菜单scanf部分代码如下:

printf("\nEnter num: ");
// 校验scanf是否成功读取1个整数
if(scanf("%d", &n) != 1){
    // 清空输入缓冲区残留的非法字符
    int ch;
    while((ch = getchar()) != '\n' && ch != EOF);
    n = -1;
    printf("输入无效,请输入合法数字\n");
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 08:24:02