如何避免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
相关产品推荐
相关产品推荐

