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
相关产品推荐
相关产品推荐

