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

while循环中使用scanf读取字符串触发Segmentation fault问题咨询

问题原因
  • 核心诱因是输入缓冲区残留的换行符导致scanf匹配失败,后续访问未初始化的野指针触发段错误,具体执行逻辑如下:
  1. %[^\n]格式符的匹配规则为读取所有非换行符的字符,遇到换行符就终止匹配,且不会将换行符从输入缓冲区中移除。第一次输入内容按下回车后,缓冲区会残留\n字符。
  2. 第二次进入循环执行scanf时,读取到的第一个字符就是残留的\n,%[^\n]直接匹配失败,此时scanf返回值为0,不会为buffer分配任何内存,buffer为未初始化的野指针。
  3. 后续直接执行printf("%s", buffer)访问野指针,直接触发段错误;同时匹配失败的场景下调用free(buffer)释放野指针也属于非法操作,同样可能引发崩溃。
修复方案

需要同时做三处修改:

  1. 初始化buffer为NULL,避免出现不确定的野指针
  2. 检查scanf的返回值,只有返回值为1(代表成功匹配1个参数)时,才操作buffer和释放内存
  3. 处理输入缓冲区残留的换行符,可以在%m[^\n]前加空格,让scanf自动跳过所有前置空白字符(包括换行符、空格、制表符等)

修复后的参考代码如下:

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

int main(){
    while(1){
        char* buffer = NULL;
        printf("inserisca una stringa \n");
        // 格式符前加空格跳过前置空白,同时校验读取结果
        if (scanf(" %m[^\n]", &buffer) == 1) {
            printf("%s\n", buffer);
            free(buffer);
        } else {
            // 异常场景清空输入缓冲区
            while(getchar() != '\n');
        }
        fflush(stdout);
    }
    return 0;
}

注意:%m是POSIX标准扩展的scanf格式符,不属于C标准语法,仅在支持POSIX标准的编译环境下可用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 19:57:00