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

C语言中用fgets读取stdin时,如何处理超长输入及解决段错误?

问题:如何限制stdin输入长度不超过缓冲区大小(仅用ferror/feof)

我被这个基础错误卡了好一阵子。想请教下,怎么避免stdin输入的字符串长度超过word_new的sizeof(也就是输入长度大于缓冲区大小),而且只能用ferror或feof函数?

补充提示:输入里没有'\n'字符,我本来想基于这点处理。
补充说明:段错误是我没贴的代码导致的,是我的问题。
补充说明:我们不用规避超长输入,而是读取char* str允许的最大字符数就行,要清楚str可能以'\n'或其他字符结尾,毕竟字符串是以'\0'结尾的。

原代码片段

int main() {

    char word_new[42];

    while(1) {
        /*此处需要帮助:运行出现段错误*/

        if (fgets(word_new, sizeof(word_new), stdin) == NULL){
            // 发生错误,调用perror
            if(ferror(stdin)){
                perror("error occured in stdin");
                exit(1);
            }
            // 无错误,仅到达EOF
            break;
        }

//此前未提供的代码片段:

char *wordpt = strchr(word_new, '\n');
*wordpt = '\0';

//无'\n'字符 => 错误

}

解决方案

首先明确:fgets本身就会自动限制读取长度——它最多读取sizeof(word_new)-1个字符,然后自动在末尾添加'\0',所以缓冲区溢出的问题fgets已经帮你解决了。你当前的段错误是因为strchr找不到'\n'时返回NULL,直接解引用*wordpt导致的。

按照要求仅用ferror和feof处理的话,修改思路如下:

  1. 保留fgets的基础逻辑,用ferror和feof区分fgets返回NULL的原因(输入错误/到达EOF)。
  2. 处理'\n'时先判断strchr的返回值,避免访问空指针。
  3. 若输入超长(无'\n'),可选清空stdin缓冲区的剩余字符,避免影响后续读取。

修改后的完整代码:

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

int main() {

    char word_new[42];

    while(1) {
        if (fgets(word_new, sizeof(word_new), stdin) == NULL){
            if(ferror(stdin)){
                perror("error occured in stdin");
                exit(1);
            }
            // 确认是到达EOF,退出循环
            if(feof(stdin)) break;
        }

        char *wordpt = strchr(word_new, '\n');
        if (wordpt != NULL) {
            *wordpt = '\0';
        } else {
            // 无换行符,说明输入超长或已到EOF
            // 清空stdin剩余字符(可选,避免残留字符干扰下一次读取)
            int c;
            while ((c = getchar()) != '\n' && c != EOF) {
                // 仅读取字符,不做额外操作
            }
            // 检查清空缓冲区时是否出错
            if (ferror(stdin)) {
                perror("error clearing stdin");
                exit(1);
            }
            // 此时word_new已是合法的'\0'结尾字符串,可正常使用
        }

        // 这里添加word_new的业务处理代码
    }

    return 0;
}

关键说明

  • fgets的安全机制:只要第二个参数传入sizeof(word_new),就不会出现缓冲区溢出,它会自动保证字符串以'\0'结尾。
  • 空指针判断:必须先检查strchr的返回值,不能直接解引用,这是解决段错误的核心。
  • 超长输入处理:清空剩余字符是可选操作,但能避免残留的输入字符被下一次fgets读取,保证逻辑连贯。
  • 符合ferror/feof要求:所有错误和EOF判断都通过这两个函数完成,满足需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 21:05:06