如何忽略输入缓冲区中的单个换行符并使 scanf return 成为一个值?
How to ignore a single newline in the input buffer and have scanf return a value?
这个问题很基础,但我在任何地方都找不到答案,所以我决定在这里提问。
基本上我有以下代码....
while (scanf(" %*[^\n]%d%c", &a, &c) != 2 || c != '\n' || a > max || a < min) {
printf("Error! Try again.");
}
...我想用它做的是确保用户在输入不正确的值时收到错误消息,并在之后立即出现新的 scanf 提示。
在大多数情况下,我已经让这个循环工作了,但是如果我在没有任何其他输入的情况下按下回车键(在输入缓冲区中只留下'\n'),scanf 只是等待更多的输入而不是终止和return正在计算一个值。虽然我知道如果 scanf 不满足任何让它 return 给调用者的条件,发生这种情况是正常的,但我一直很难强迫它在其缓冲区中以单个换行符终止。在这里,我假设在第一个格式说明符之前留下 space 会有所帮助(以便可以忽略单个换行符),但无论出于何种原因,它似乎都无济于事。有谁知道我如何在保持现有代码不变的情况下解决这个问题(如果可能的话)?
你必须改变处理问题的策略。
- 使用
fgets
读取一行文本。
- 使用
sscanf
从行中提取数据。如果该行没有数据,重复。
char line[LINE_SIZE];
while ( fgets(line, LINE_SIZE, stdin) )
{
if ( sscanf(line, "%d", &a) != 1 || a > max || a < min)
{
printf("Error! Try again.");
}
else
{
break;
}
}
如果你想严格执行一个数字后跟一个换行符,你可以使用:
if ( sscanf(line, "%d%c", &a, &c) != 2 || c != '\n' || a > max || a < min)
这个问题很基础,但我在任何地方都找不到答案,所以我决定在这里提问。
基本上我有以下代码....
while (scanf(" %*[^\n]%d%c", &a, &c) != 2 || c != '\n' || a > max || a < min) {
printf("Error! Try again.");
}
...我想用它做的是确保用户在输入不正确的值时收到错误消息,并在之后立即出现新的 scanf 提示。
在大多数情况下,我已经让这个循环工作了,但是如果我在没有任何其他输入的情况下按下回车键(在输入缓冲区中只留下'\n'),scanf 只是等待更多的输入而不是终止和return正在计算一个值。虽然我知道如果 scanf 不满足任何让它 return 给调用者的条件,发生这种情况是正常的,但我一直很难强迫它在其缓冲区中以单个换行符终止。在这里,我假设在第一个格式说明符之前留下 space 会有所帮助(以便可以忽略单个换行符),但无论出于何种原因,它似乎都无济于事。有谁知道我如何在保持现有代码不变的情况下解决这个问题(如果可能的话)?
你必须改变处理问题的策略。
- 使用
fgets
读取一行文本。 - 使用
sscanf
从行中提取数据。如果该行没有数据,重复。
char line[LINE_SIZE];
while ( fgets(line, LINE_SIZE, stdin) )
{
if ( sscanf(line, "%d", &a) != 1 || a > max || a < min)
{
printf("Error! Try again.");
}
else
{
break;
}
}
如果你想严格执行一个数字后跟一个换行符,你可以使用:
if ( sscanf(line, "%d%c", &a, &c) != 2 || c != '\n' || a > max || a < min)