如何阻止scanf遗留的换行符进入后续填充的char数组?
解决scanf遗留换行符导致char数组首元素为'\n'的问题
问题根源
你代码里的问题出在scanf读取整数后会把输入的换行符留在输入缓冲区。比如执行scanf("%d", &n)时,你输入数字后按回车,scanf只取走了数字,换行符\n还留在缓冲区里。接下来调用getNum时,fgetc(stdin)会先读到这个换行符,直接存进num[0],这就是你看到的首元素是\n的原因。
高效解决方案
不需要用isdigit/isalpha过滤,直接从输入缓冲区处理入手,以下是几种高效方案:
方案1:读取完整数后清空缓冲区剩余字符
在每次用scanf读取整数后,手动把缓冲区里的换行符(及其他残留字符)清掉:
int main(){ char num[LEN]; int n, base1, base2, length; scanf("%d", &n); // 清除scanf留下的换行符 while (getchar() != '\n'); for(int i=0; i<n;i++){ length=getNum(num); scanf("%d %d", &base1, &base2); // 清除本次scanf后的换行符 while (getchar() != '\n'); convert(num, base1, base2, length); } }
注:该方法适合你的输入格式(每行是数字串+两个基数),会一并清除整数后的所有残留字符直到换行。
方案2:修改getNum函数,先跳过所有空白字符
让getNum在读取有效字符前,先跳过所有空白(包括换行、空格、制表符等),从第一个非空白字符开始读取:
int getNum(char *num){ char c; int i=0; // 跳过所有空白字符 while((c=fgetc(stdin)) != EOF && isspace(c)); if(c == EOF) return 0; // 处理输入结束的异常情况 num[i++] = c; // 读取到空格为止 while((c=fgetc(stdin)) != ' ' && c != EOF){ num[i]=c; i++; } return i; }
该方法更健壮,不管缓冲区里有没有残留空白,都能正确读取目标字符串。
方案3:直接用scanf读取字符串,自动跳过空白
完全去掉getNum函数,利用scanf("%s")的特性:它会自动跳过前面的所有空白字符,然后读取到下一个空白(空格/换行)为止,代码更简洁:
#include <string.h> // 需要引入strlen的头文件 int main(){ char num[LEN]; int n, base1, base2, length; scanf("%d", &n); for(int i=0; i<n;i++){ // scanf自动跳过前面的空白,读取num到空格为止 scanf("%s %d %d", num, &base1, &base2); length = strlen(num); // 获取字符串长度 convert(num, base1, base2, length); } }
这是处理这类输入场景的常用方式,完全避免了手动处理缓冲区的麻烦。
额外提示
不管用哪种方案,都要注意数组越界问题:LEN是10000,但如果输入的字符串超过这个长度会导致溢出。实际使用时可以添加限制,比如方案3里用scanf("%9999s", num)(预留一个位置给字符串结束符\0),方案2里在循环里加i < LEN-1的判断,避免数组溢出。
内容的提问来源于stack exchange,提问作者Someone Someone
相关产品推荐
相关产品推荐

