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

C语言如何限制scanf获取字符串的允许输出字符?

问题根因
  • 条件判断语法错误:你写的if (b[i] == '.','-')用到了C语言的逗号运算符,逗号运算符的规则是依次执行左侧所有表达式,最终返回最后一个表达式的值作为整体结果。这里最后一个表达式是字符常量'-',它的ASCII值非0,所以整个判断条件永远为真,所有字符都会被输出,自然失去了过滤效果。
  • 循环逻辑错误:for循环已经自带i++迭代逻辑,你在else分支又额外加了一次i++,会导致每次命中不合法字符时直接跳过下一个字符的校验,属于逻辑漏洞。
  • 潜在安全问题:scanf("%s", b)没有限制输入长度,你的字符数组b只有5字节容量,用户输入超过4个字符时会触发缓冲区溢出,存在安全风险。
修复方案

如果要自定义允许输出的字符,推荐用可配置的合法字符集合方案,后续新增/删除合法字符只需修改一处即可,不需要改判断逻辑。
修正后的完整代码如下:

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

// 在这里自定义所有允许输出的字符,新增删除只需要改这个字符串即可
#define ALLOWED_CHARS ".-"

int main(int argc, char *argv[])
{
    // 多留1位存字符串结束符'\0'
    char b[6];
    int i;
    
    printf("enter characters (only first 5 allowed characters will be shown):");
    // 限制scanf最多读取5个字符,避免缓冲区溢出
    scanf("%5s", b); 
    
    for(i = 0; i < 5 && b[i] != '\0'; i++)
    {
        // 检查当前字符是否在允许的字符集合中
        if (strchr(ALLOWED_CHARS, b[i]) != NULL)
        {
            printf("%c", b[i]);
        }
    }
    
    printf("\n");
    return 0;
}

方案说明

  • 如果允许的字符较少,也可以直接用逻辑或写判断条件:if (b[i] == '.' || b[i] == '-'),效果和上面的写法一致。
  • 用strchr的方案更适合合法字符数量多的场景,后续要新增允许的字符比如数字、字母,直接修改ALLOWED_CHARS的定义即可,比如要允许0-9的数字就改成#define ALLOWED_CHARS ".-0123456789"。
  • 代码里已经修复了缓冲区溢出和循环跳字符的问题,同时增加了字符串结束符判断,避免读取到数组里的垃圾值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 14:54:04