令 X 为以下语句...
我确实知道 scanf 的工作原理
令 Y 为以下语句...
...但是第二个值去哪里了?
X 和 Y 不对应。要么你知道scanf 的返回值,要么你不知道scanf 是如何工作的。这是底线。
...但是第二个值去哪里了?
根据the fscanf manual,
fscanf() 函数应依次执行格式的每个指令。如果指令失败,如下所述,函数将返回。失败被描述为输入失败(由于输入字节不可用)或匹配失败(由于输入不当)。
空格指令与. 输入不匹配,这将导致匹配失败,scanf 将返回,这意味着. 字节之外的任何内容都将消耗来自@ 987654328@。事实上,scanf 甚至会在 . 返回之前将. 放回 stdin... 这不是很好吗? p>
我想你明白这一点(因为你说“我确实知道 scanf 是如何工作的”),但你似乎在询问第二个 value,由于先前的匹配失败...因此,您的第一个问题的答案是,第二个值不存在。它还不存在,因为在它之前存在输入格式错误。
虽然我们在讨论 scanf、返回值和匹配失败的主题,但对于剩下的问题,我将假设您的代码实际上看起来更像这样:
int i = 0;
int q = 0;
if (scanf("%d %d", &i, &q) != 2) {
puts("Discarding invalid input");
scanf("%*[^\n]"); // discard up to the next newline and...
getchar(); // discard that newline, too.
// XXX: You might want to `return` or `continue` or something
}
...我怎样才能将它存储在我的变量中?
如前所述,空格指令与句点不匹配。您需要将其替换为按您的意图操纵输入流的东西......这对我来说很难回答,因为我没有这些信息,但我建议:拆分两个 conversions 对scanf 进行两次单独的调用。这应该在两次调用scanf 之间为您提供一个不错的位置,以插入您的周期处理代码。
以下是我为这种输入采用的习语的前后对比:
// BEFORE // AFTER
if (scanf("%d %d", &i, &q) != 2) { if (scanf("%d", &i) != 1) {
// ... puts("Invalid first input...");
// XXX: Handle this???
// XXX: `return` or `continue` or something
}
// XXX: Read a character, check if it's a space (or a dot, or something else which you have in your mind and I don't have in mine)
if (scanf("%d", &q) != 1) {
// ...
处理错误期间可以很简单,例如退出进程或调用getchar() 丢弃单个字符,然后调用continueing 以重试。这些解决方案无法解决所有用户输入错误,甚至可能让一些用户感到困惑或沮丧。我建议坚持使用 丢弃其余行 方法,至少在您了解所有可供用户输入的替代方法 以及它们各自擅长什么之前。毕竟,人们倾向于避免使用让他们感到困惑的软件......
...因此人们倾向于不鼓励 scanf... 因为我猜 没有文献可以设定标准,因此 没有办法纠正我与scanf相关的误解。