admin | 世界杯冰岛
当您在这里提示用户使用第一个scanf时
代码语言:javascript复制char opt;
scanf(" %c", &opt);当用户输入一个字符时,比如A,"A\n“放置在缓冲区中,\n来自用户按下返回键。scanf根据请求使用" %c"格式字符串接收一个字符,并将\n留在缓冲区中。
当第二个scanf被执行为
代码语言:javascript复制printf("Please Enter a New Name:");
char name[200];
scanf("%[^\n]s", name);格式字符串"%[^\n]s"请求它读取,直到遇到\n,请注意,您的缓冲区已经包含了一个\n作为第一个字符,因此scanf返回时没有读取任何内容,仍然将\n留在缓冲区中。
当第三个scanf被执行为:
代码语言:javascript复制printf("Please Enter a New Code:");
char code[200];
scanf("%s", code);(在chqrlie的评论后更正)
格式字符串"%s"忽略了前面的空格,因此现在\n被忽略了,scanf很高兴地等待输入。
注意格式字符串" %c"中的前导空格,空格是用来使scanf忽略前导空格的,您可以用第二个scanf实现相同的逻辑。您可以确保所有连续的scanf都忽略缓冲区中的\n,这是大多数格式说明符都会忽略的,或者您可以确保任何scanf都不会让它首先使用"<...>%*c"之类的东西来消除它。尽管所有这些方法都不是可靠和一致的方法,而且正如无数次所说的那样,scanf并不是为了执行这样的任务,比如接收用户输入,您应该寻找替代的方法。
而且,s in "%[^\n]s"当然不像您所期望的那样。scanf的手册页声明:
一个普通字符(即除空白或‘%’以外的其他字符)。此字符必须与输入的下一个字符完全匹配。
如果匹配,scanf就放弃它,继续按照其余的格式说明符进行解析。如果没有,scanf就会停在那里返回。因为它位于格式字符串的末尾,所以它会以任何方式返回,从而向您隐藏潜在的bug。