scanf首次使用正常、二次使用失效的原因及解决方案咨询
问题描述
我需要接收用户输入类似“1 2”“0 0”“2 2”“0 1”格式的内容。首次输入符合要求时程序运行正常,但首次输入错误后,程序提示重新输入,此时新输入出现错位:第一个变量为空,第二个变量获取到原本给第一个的值。我尝试使用语句while( ( c = getchar() ) != EOF && c != '\n');清理输入缓冲区,但问题仍未解决,请问这是怎么回事?
代码示例
#include <stdio.h> #include <stdlib.h> int validation(); int main ( void ) { int valid = 0; while ( valid == 0 ){ valid = validation(); } return 0; } int validation(){ char cfirst, csecond; int first, second, c; printf("Please enter your number:\n"); scanf("%c %c", &cfirst, &csecond); printf("cfirst = %c, csecond = %c\n", cfirst, csecond); if( cfirst == '0' ){ first = 0; } else if( ( cfirst == '1' || cfirst == '2' ) ){ first = cfirst - '0'; // alternative to atoi for a singular character } else{ printf("Move rejected. Please try again\n"); while( ( c = getchar() ) != EOF && c != '\n'); return 0; } if( csecond == '0'){ second = 0; } else if( csecond == '1' || csecond == '2' ){ second = csecond - '0'; // alternative to atoi for a singular character } else{ printf("Move rejected. Please try again\n"); while( ( c = getchar() ) != EOF && c != '\n'); return 0; } //first = cfirst - '0'; //second = csecond - '0'; printf("Your first number = %d\n", first); printf("Your second number = %d\n", second); return 0; }
问题分析与解决
核心原因
%c格式符的特性:scanf的%c格式符不会自动跳过前导空白字符(包括换行、空格、制表符)。当首次输入错误并清理缓冲区后,输入缓冲区中残留的换行符(或其他空白)会被下一次调用的scanf的第一个%c直接读取,导致后续输入错位。- 返回值逻辑错误:
validation函数无论输入是否合法,最终都返回0,导致main中的循环无限执行,即使输入合法也无法退出。
修复方案
1. 修改scanf格式串,跳过前导空白
将scanf("%c %c", &cfirst, &csecond);修改为:
scanf(" %c %c", &cfirst, &csecond);
格式串开头的空格会让scanf自动跳过所有前导空白字符,确保第一个%c读取到的是用户输入的有效字符,而非残留的换行或空格。
2. 修正返回值逻辑
当输入验证通过时,让validation函数返回1,使main中的循环正常退出:
// 在函数末尾,验证通过后返回1 printf("Your first number = %d\n", first); printf("Your second number = %d\n", second); return 1; // 替换原来的return 0;
3. 优化缓冲区清理逻辑(可选)
虽然修改格式串已能解决问题,但可以进一步优化错误处理时的缓冲区清理,确保所有残留字符被清空:
else{ printf("Move rejected. Please try again\n"); while( ( c = getchar() ) != EOF && c != '\n'); // 如果遇到EOF,直接退出程序或做相应处理 if(c == EOF){ exit(1); } return 0; }
内容的提问来源于stack exchange,提问作者Timbin
相关产品推荐
相关产品推荐

