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

为何scanf("%s", val);返回NULL?单字符读取及malloc相关问题

问题分析与解决

原代码的核心问题

  1. 野指针导致未定义行为:char *val;仅声明了指针,未指向任何有效内存。调用scanf("%s", val)时,会往随机内存地址写入数据,必然引发程序异常(比如返回NULL、崩溃)。
  2. malloc使用未限制读取长度:%s格式符默认会持续读取输入,直到遇到空白字符(空格、回车、制表符),这就是输入单个字符后程序仍等待的原因。

正确实现方式

方式一:栈上数组实现(简单高效)

只需存储单个字符+字符串终止符\0,直接定义长度为2的数组即可:

#include <stdio.h>

int main(int argc, char *argv[])
{
    char val[2]; // 1字节存字符,1字节存终止符
    if (argc == 2)
    {
        // 确保取到的是单个字符并补全终止符
        val[0] = argv[1][0];
        val[1] = '\0';
    }
    else
    {
        // %1s 限制仅读取1个非空白字符,自动添加终止符
        scanf("%1s", val);
    }
    printf("Val = %s", val);
    return 0;
}

方式二:动态内存分配(malloc)

若必须用char*动态分配,需至少申请2字节空间,同时限制scanf读取长度:

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

int main(int argc, char *argv[])
{
    char *val = malloc(2); // 分配2字节:字符位+终止符位
    if (!val) { // 检查内存分配是否成功
        printf("内存分配失败\n");
        return 1;
    }
    
    if (argc == 2)
    {
        val[0] = argv[1][0];
        val[1] = '\0';
    }
    else
    {
        scanf("%1s", val); // 强制只读1个字符
    }
    
    printf("Val = %s", val);
    free(val); // 释放动态分配的内存
    return 0;
}

额外说明

如果需要读取任意单个字符(包括空格、回车这类空白字符),可替换scanf为getchar():

// 替换else分支的scanf代码
val[0] = getchar();
val[1] = '\0';

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 23:42:28