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

C语言中用fgets()从STDIN获取输入:替代goto的高效实现方案

关于fgets处理用户输入的问题解答

原代码示例

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

#define MAXSIZE 10

int main(int argc, char *argv[]){
    char input[MAXSIZE], c, *input_ptr;
    input_tag: printf("Enter the initial data string : ");
    input_ptr = fgets(input, MAXSIZE, stdin);                    //get input
    if(input_ptr != NULL && strcspn(input,"\n") == MAXSIZE-1){   //check if input fits in buffer
        printf("Buffer overflow. Reduce size of input.\n");
        while((c = getchar()) != '\n')                           //loop through rest of STDIN to discard extra characters until newline
        goto input_tag;                                          //Request for user input again
    }
    input[strcspn(input,"\n")] = '\0';                           //Remove newline character
    printf("Input is %s\n", input);
    return 0;
}

技术问题与解答

1. 是否存在更高效的方式,使用fgets()持续从STDIN获取用户输入?

原代码的核心逻辑没问题,但可以通过减少冗余操作提升效率:

  • 复用strcspn的返回值,避免两次调用该函数;
  • 单独封装缓冲区清理逻辑,避免重复代码;
  • 处理fgets返回NULL的情况(比如用户输入EOF),防止程序陷入异常流程。

2. 能否不使用goto语句来持续请求用户输入?

完全可以。用结构化循环(do-while或while)就能替代goto的跳转逻辑,把输入、校验、重试的流程封装在循环体内,逻辑更线性易读。

3. 有没有更好的实现方式?(避免goto)

下面是优化后的实现,用do-while循环替代goto,同时完善异常处理与代码结构:

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

#define MAXSIZE 10

// 清理输入缓冲区剩余字符,直到换行或EOF
void clear_stdin(void) {
    int c;
    while ((c = getchar()) != '\n' && c != EOF);
}

int main(int argc, char *argv[]) {
    char input[MAXSIZE];
    char *input_ptr;
    size_t input_len;
    int valid_input = 0;

    do {
        printf("Enter the initial data string : ");
        input_ptr = fgets(input, MAXSIZE, stdin);

        // 处理输入错误或EOF
        if (input_ptr == NULL) {
            printf("\nInput error or EOF received.\n");
            break;
        }

        input_len = strcspn(input, "\n");
        // 检查输入是否超出缓冲区
        if (input_len == MAXSIZE - 1 && input[MAXSIZE - 1] != '\n') {
            printf("Buffer overflow. Reduce size of input.\n");
            clear_stdin();
        } else {
            input[input_len] = '\0';
            valid_input = 1; // 标记输入有效,退出循环
        }
    } while (!valid_input);

    if (valid_input) {
        printf("Input is %s\n", input);
    }
    return 0;
}

这个实现的优势:

  • 用结构化循环替代goto,符合现代编程规范,逻辑更易追踪;
  • 封装缓冲区清理函数,代码复用性更强;
  • 处理了fgets返回NULL的边界情况,程序鲁棒性更高;
  • 复用strcspn结果,减少冗余计算;
  • 代码分层清晰,输入、校验、处理步骤明确,可读性更好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 18:47:25