使用scanf多格式匹配输入时程序持续等待的问题咨询
这个问题的核心原因其实出在scanf对%c格式说明符的处理逻辑,以及格式字符串的严格匹配规则上,我来给你拆解清楚:
%c不会自动跳过空白字符
你用的长格式字符串里的%c,和%d这类格式说明符的行为不一样:%d会自动忽略输入中的空格、换行、制表符等空白字符,直接读取有效数字;但%c会原封不动读取输入缓冲区里的第一个字符——不管它是不是空白。
举个例子,如果你输入时不小心在运算符前后加了空格(比如31/8 +7/4),或者分两次输入(先输31/8按回车,再输+7/4),%c就会读取到空格或换行符,而不是你想要的+。接下来的%d试图读取数字,但此时输入缓冲区里的下一个字符是+,不是有效数字,scanf就会一直卡在那里等待正确的数字输入,导致程序看起来毫无反应。
而你用getchar()的方式时,若输入的是连续的31/8+7/4,getchar()刚好读到+,后续的scanf("%d/%d")又会自动跳过空白去匹配数字和/,所以能正常运行。格式字符串的严格匹配要求
scanf的格式字符串里,除了%d、%c这类格式说明符,其他字符(比如你写的/)必须和输入内容完全对应。如果输入中任何地方不符合这个格式(比如少打了一个/,或者多了一个空格),scanf就会停止匹配,一直等待你输入符合要求的内容。而分开读取的方式,每个scanf只处理一小部分逻辑,容错性更高——比如scanf("%d/%d")会自动跳过开头的空白,再去匹配数字+/+数字,不会因为一点点小偏差就卡住。
修复方法
要解决这个问题很简单,只要在%c前面加一个空格即可,修改后的scanf语句如下:
scanf("%d/%d %c%d/%d", &num1, &denom1, &sign, &num2, &denom2);
这里的空格会告诉scanf:先跳过所有空白字符,再读取第一个非空白字符作为运算符。这样不管你输入时运算符前后有没有空白,都能正确读取到+、-等符号,后续的数字匹配也能正常完成。
内容的提问来源于stack exchange,提问作者Yaachaka

