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

scanf扫描集%1[x+-/]与%1[x/+-]行为差异原因探究

问题

扫描集%1[x+-/]与%1[x/+-]存在行为差异:前者会接受逗号(,)和句号(.),后者则拒绝这些字符。以下是验证该差异的C语言代码及运行结果,请问为何这两个scanf扫描集的行为会有此类差异?

代码示例

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

char scanoperator ( ) {
    int scanned = 1;
    char operator[2] = "";
    char nl[2] = "";

    do {
        if ( ! scanned) {
            printf ( "try again\n");
        }
        scanned = scanf ( "%1[x+-/]", operator);
        if ( EOF == scanned) {
            fprintf ( stderr, "EOF\n");
            exit ( 1);
        }
        scanf ( "%*[^\n]"); // 扫描并丢弃换行前的所有字符
        scanf ( "%1[\n]", nl); // 扫描换行符
    } while ( ! scanned);
    return operator[0];
}

char scanop ( ) {
    int scanned = 1;
    char operator[2] = "";
    char nl[2] = "";

    do {
        if ( ! scanned) {
            printf ( "try again\n");
        }
        scanned = scanf ( "%1[x/+-]", operator);
        if ( EOF == scanned) {
            fprintf ( stderr, "EOF\n");
            exit ( 1);
        }
        scanf ( "%*[^\n]"); // 扫描并丢弃换行前的所有字符
        scanf ( "%1[\n]", nl); // 扫描换行符
    } while ( ! scanned);
    return operator[0];
}

int main ( void) {
    char op;

    printf ( "Select the operator((+ - x /)\n");
    op = scanoperator ( );
    printf ( "operator is %c\n", op);

    printf ( "Select the operator((+ - x /)\n");
    op = scanop ( );
    printf ( "operator is %c\n", op);

    return 0;
}

运行结果

Select the operator((+ - x /)
.
operator is .
Select the operator((+ - x /)
.
try again

调用scanoperator()会接受句号(.),而调用scanop()则会正确输出"try again"。

原因分析

问题出在scanf扫描集中-符号的特殊用法上:当-夹在两个字符中间时,它表示一个ASCII码的字符范围(从左边字符到右边字符之间的所有字符);只有当-在扫描集的开头或结尾时,才会被当作普通的-字符处理。

  • 对于扫描集%1[x+-/]:
    这里的-位于+和/之间,会被解析为「从+(ASCII码43)到/(ASCII码47)的所有字符」,这个区间包含了+(43)、,(44)、-(45)、.(46)、/(47),再加上扫描集里的x(ASCII码120),所以这个扫描集实际会匹配x、+、,、-、.、/这些字符,这就是输入.会被接受的原因。

  • 对于扫描集%1[x/+-]:
    这里的-在扫描集的最后,只作为普通字符处理,所以这个扫描集仅匹配x、/、+、-四个指定字符,输入.不在其中,自然会被拒绝,触发try again提示。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 12:47:20