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

C语言scanf输入异常、循环重复输出问题排查求助

排查C代码中文件操作与输入循环的两个问题

我来帮你拆解这两个问题的根源,以及对应的修复方案:

问题1:TOS输入环节重复输出“TOS:”提示

原因

在TOS的验证循环中,当你输入的内容不匹配文件中的任何行时,while(fgets(line, BUFFER_SIZE, fptr))会一直读取到文件末尾,此时文件指针停留在文件结尾。而你只在整个TOS循环结束后调用了rewind(fptr),循环内部每次验证失败时没有重置指针,导致下一次循环时fgets直接返回NULL,根本不会进入匹配检查的循环,stat始终为0,因此会一直重复输出“TOS:”提示。

修复

在每次执行while(fgets...)匹配检查前,先调用rewind(fptr)将文件指针重置到文件开头,确保每次验证都从文件起始位置读取内容,同时找到匹配后直接跳出循环提升效率:

stat = 0;
while (stat == 0) {
    printf("TOS: ");
    scanf("%s", tos);
    rewind(fptr); // 每次检查前重置文件指针
    while (fgets(line, BUFFER_SIZE, fptr) != NULL) {
        if (strstr(line, tos)) {
            stat = 1;
            break; // 找到匹配后直接结束读取
        }
    }
}

问题2:部分输入步骤被跳过,直接进入Total Fee环节

原因

这个问题主要由三个错误叠加导致:

  1. 数组参数传递错误:你在scanf中给数组加了&,比如scanf("%s", &v_id);。数组名v_id本身就是指向数组首元素的指针,加&会导致类型不匹配,这种未定义行为可能破坏内存中的其他变量(比如stat的值),导致循环提前结束,跳过输入步骤。
  2. 文件指针重置不及时:和TOS的问题一样,Customer Status、Needed Days的验证循环中,都没有在每次检查前重置文件指针,导致文件指针停留在末尾,无法读取内容,可能意外让stat的逻辑出错。
  3. getchar()的滥用:在TOS和Customer Status输入后调用getchar(),如果输入缓冲区中没有多余字符,getchar()会等待用户输入,反而打乱流程;scanf("%s")本身会自动跳过开头的空白字符(包括换行),不需要额外调用getchar()。

修复

  • 所有scanf中传递数组参数时,去掉&,比如scanf("%s", v_id);、scanf("%s", tos);等。
  • 每个输入验证循环中,都在fgets检查前调用rewind(fptr)重置指针。
  • 去掉不必要的getchar()调用。

完整修复后的代码示例

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define BUFFER_SIZE 1024 // 定义合理的缓冲区大小

int main() { 
    int stat; 
    char v_id[100], c_id[100], line[BUFFER_SIZE], tos[100], cust_stat[100], n_daysasd[100], tot_fee[100];
    
    printf("Enter Visitor ID: "); 
    scanf("%s", v_id); 
    printf("Enter Customer ID: "); 
    scanf("%s", c_id); 

    FILE* fptr2; 
    FILE* fptr; 
    FILE* ftemp; 
    // 添加文件打开失败判断,增强健壮性
    if ((fptr = fopen(v_id, "r")) == NULL) {
        perror("Failed to open visitor file");
        return 1;
    }
    if ((fptr2 = fopen("servicestest.txt", "r")) == NULL) {
        perror("Failed to open servicestest.txt");
        fclose(fptr);
        return 1;
    }
    if ((ftemp = fopen("replacetemp.txt", "w")) == NULL) {
        perror("Failed to create temp file");
        fclose(fptr);
        fclose(fptr2);
        return 1;
    }

    // 打印文件内容
    while (fgets(line, BUFFER_SIZE, fptr)) { 
        printf("%s\n", line); 
    } 
    printf("\nEnter the information accordingly\n"); 
    rewind(fptr); 

    // TOS输入验证
    stat = 0; 
    while (stat == 0) { 
        printf("TOS: "); 
        scanf("%s", tos); 
        rewind(fptr); 
        while (fgets(line, BUFFER_SIZE, fptr) != NULL) { 
            if (strstr(line, tos)) { 
                stat = 1; 
                break; 
            } 
        } 
    } 

    // Customer Status输入验证
    stat = 0; 
    while (stat == 0) { 
        printf("Customer Status: "); 
        scanf("%s", cust_stat); 
        rewind(fptr); 
        while (fgets(line, BUFFER_SIZE, fptr) != NULL) { 
            if (strstr(line, cust_stat)) { 
                stat = 1; 
                break; 
            } 
        } 
    } 

    // Needed Days输入验证
    stat = 0; 
    while (stat == 0) { 
        printf("Needed days: "); 
        scanf("%s", n_daysasd); 
        rewind(fptr); 
        while (fgets(line, BUFFER_SIZE, fptr) != NULL) { 
            if (strstr(line, n_daysasd)) { 
                stat = 1; 
                break; 
            } 
        } 
    } 

    // Total Fee输入验证
    stat = 0; 
    while (stat == 0) { 
        printf("Total Fee: "); 
        scanf("%s", tot_fee); 
        rewind(fptr); 
        while (fgets(line, BUFFER_SIZE, fptr) != NULL) { 
            if (strstr(line, tot_fee)) { 
                stat = 1; 
                break; 
            } 
        } 
    } 

    // 更新servicestest.txt内容
    rewind(fptr2); 
    while (fgets(line, BUFFER_SIZE, fptr2)) { 
        if (strstr(line, v_id)) { 
            fprintf(ftemp, "Visit ID: %s, Customer ID : %s, TOS : %s, Customer Status : %s, Needed Days : %s, Total Fee : %s, Payment : Not Made\n", v_id, c_id, tos, cust_stat, n_daysasd, tot_fee);
        } else { 
            fputs(line, ftemp); 
        } 
    } 

    fclose(fptr); 
    fclose(fptr2); 
    fclose(ftemp); 
    remove("servicestest.txt"); 
    rename("replacetemp.txt", "servicestest.txt");

    return 0;
}

额外建议

  • 记得添加必要的头文件,否则strstr、perror等函数会报错。
  • 在fprintf的末尾添加\n,避免写入的内容和下一行连在一起,保持文件格式整洁。
  • 添加文件打开失败的判断,能快速定位文件不存在、权限不足等问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 20:12:45