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

如何避免scanf将ISBN中的连字符识别为负号?

解决带连字符ISBN的逐数字读取问题

你的问题出在scanf的格式字符串使用错误:%d会读取连续数字作为整数,且会把连字符-识别为负号,导致多位数和负数存入数组。要实现逐个读取ISBN的每一位数字,同时忽略连字符,有以下几种可行方案:

方案一:修改scanf格式字符串,指定单数字读取

利用%1d格式符强制读取单个数字,同时在格式字符串中保留连字符作为匹配项(scanf会自动匹配输入中的连字符,无需存储)。代码如下:

int a[11]; // 对应你使用的a[1]到a[10]下标
scanf("%1d-%1d%1d%1d-%1d%1d%1d%1d%1d-%1d", 
      &a[1], &a[2], &a[3], &a[4], 
      &a[5], &a[6], &a[7], &a[8], &a[9], &a[10]);

输入0-670-82162-4时,每个%1d会单独读取一位数字,连字符会被格式字符串匹配跳过,最终数组内容就是你期望的0 6 7 0 8 2 1 6 2 4。

方案二:先读取整串ISBN,再遍历提取数字

这种方法更灵活,不受固定格式限制,适合处理任意位置有连字符的情况:

#include <cstdio>
#include <cctype>

int main() {
    char isbn[20];
    int a[11], idx = 1;
    scanf("%s", isbn); // 读取整个ISBN字符串
    
    for (int i = 0; isbn[i] != '\0'; i++) {
        if (isdigit(isbn[i])) {
            a[idx++] = isbn[i] - '0'; // 字符转数字:利用ASCII码差值转换
        }
    }
    
    // 验证输出
    for (int i = 1; i <= 10; i++) {
        printf("%d ", a[i]);
    }
    return 0;
}

遍历字符串时跳过非数字字符,将每个数字字符转换为整数存入数组,最终得到目标结果。

方案三:循环读取数字并跳过分隔符

通过循环逐个读取数字,每次读取后跳过所有非数字字符(直到下一个数字或换行):

#include <cstdio>
#include <cctype>

int main() {
    int a[11], idx = 1;
    int c;
    
    while (idx <= 10) {
        scanf("%d", &a[idx++]);
        // 跳过后续非数字字符
        while ((c = getchar()) != '\n' && !isdigit(c));
        if (c != '\n') {
            ungetc(c, stdin); // 将下一个数字字符放回输入流,供下一次scanf读取
        }
    }
    
    // 验证输出
    for (int i = 1; i <= 10; i++) {
        printf("%d ", a[i]);
    }
    return 0;
}

这种方法无需依赖固定的ISBN格式,只要输入中包含10个数字即可正确提取。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 21:31:04