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

C语言scanf使用%*c%c时第二段代码无法正常接收输入问题

问题根因与解决方法

先搞懂核心原理(不用记底层,记规则就行)

所有你从键盘敲的内容,包括按的回车、不小心敲的空格,都会先存在一块叫「输入缓冲区」的临时内存里,scanf不是直接读你实时敲的键,是从这个缓冲区里取内容。不同格式符的读取规则差很多:

  • %d(读整数):会自动跳过缓冲区开头所有的空白(空格、回车、Tab缩进),碰到数字才开始读,读完数字就停下,数字后面跟着的回车/空格会留在缓冲区里。
  • %c(读单个字符):不跳过任何内容,缓冲区当前排在第一个的字符是什么,它就直接读走,哪怕这个字符是你上一次输入完按的回车。

你教授说的%*c,作用是读1个字符但不存到变量里、直接扔掉,本意是想扔掉上一次输入残留的回车,再读你新输入的有效字符。

为什么会出现跳过输入的bug

%*c%c这个写法本身有很大的局限性,它只能在「缓冲区里恰好剩1个需要扔掉的残留字符」的场景下生效,只要不符合这个前提就会出问题:

  • 如果缓冲区是空的(比如程序刚启动跑第一个输入、或者上一次把缓冲区内容读完了),%*c不会等你输完有效选项再扔,它会直接把你敲的第一个有效字符(比如选咖啡类型敲的L/B)扔掉,后面的%c就读到你按的回车,相当于这步输入白敲了。
  • 如果你输完上一个内容后多按了一次回车、或者不小心敲了空格,缓冲区里残留的空白字符就不止1个,%*c只能扔掉1个,剩下的回车/空格会被后面的%c直接读走,scanf不会停下来等你输入,直接执行下一行代码,就是你看到的「跳过输入环节直接显示后续内容」的现象。

你第一段代码能正常跑只是巧合:你输入的时候每次都刚好只按一下回车,不多敲多余字符,刚好凑上了%*c只扔1个字符的要求,跑到第二段的时候只要有一次输入多带了一个空白字符,整个后续输入流程就全乱了。

零出错的简单改法

根本不需要用%*c来手动算要扔几个字符,只要记住一个规则:所有用来读单个字符的%c,前面加一个空格就行。

格式串里的空格,对scanf来说意思是「跳过缓冲区里所有连续的空白字符,不管有多少个,直到碰到第一个非空白的有效字符再开始读」,不管你之前残留了多少回车、空格,全都会被自动跳过,不会读走你输入的有效字符,也不会出现跳过输入的问题。

改完的代码如下:

printf("COFFEE-1...\n");
printf("Type ([L]ight,[B]lend): ");
scanf(" %c", &type1);  // 注意%c前的空格,不要漏
printf("Grind size ([C]ourse,[F]ine): ");
scanf(" %c", &grind1);
printf("Bag weight (g): ");
scanf("%d", &weight1); // %d默认会跳过空白,不需要修改
printf("Best served with cream ([Y]es,[N]o): ");
scanf(" %c", &cream1);
printf("Ideal serving temperature (Celsius): ");
scanf("%d", &temp1);

printf("\nCOFFEE-2...\n");
printf("Type ([L]ight,[B]lend): ");
scanf(" %c", &type2);
printf("Grind size ([C]ourse,[F]ine): ");
scanf(" %c", &grind2);
printf("Bag weight (g): ");
scanf("%d", &weight2);
printf("Best served with cream ([Y]es,[N]o): ");
scanf(" %c", &cream2);
printf("Ideal serving temperature (Celsius): ");
scanf("%d", &temp2);

改完之后不管你输入的时候多按几次回车、不小心敲了空格,都不会出现输入被跳过的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 11:24:37