C语言 scanf() 将新行字符留在缓冲区中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5240789/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 07:59:40  来源:igfitidea点击:

scanf() leaves the new line char in the buffer

cscanf

提问by ipkiss

I have the following program:

我有以下程序:

int main(int argc, char *argv[])
{
  int a, b;
  char c1, c2;
  printf("Enter something: ");
  scanf("%d",&a); // line 1
  printf("Enter other something: ");
  scanf("%d", &b); // line 2

  printf("Enter a char: ");
  scanf("%c",&c1); // line 3
  printf("Enter another char: ");
  scanf("%c", &c2); // line 4

  printf("Done"); // line 5

  system("PAUSE");

  return 0;
}

As I read in the C book, the author says that scanf()left a new line character in the buffer, therefore, the program does not stop at line 4 for user to enter the data, rather it stores the new line character in c2 and moves to line 5.

正如我在C书中读到的,作者说scanf()在缓冲区中留下了一个换行符,因此,程序不会停在第4行供用户输入数据,而是将换行符存储在c2中并移动到第 5 行。

Is that right?

那正确吗?

However, does this only happen with chardata types? Because I did not see this problem with intdata types as in line 1, 2, 3. Is it right?

然而,这只发生在char数据类型上吗?因为我没有看到int第 1、2、3 行的数据类型有这个问题。对吗?

采纳答案by Jeremiah Willcock

The scanf()function skips leading whitespace automatically before trying to parse conversions other than characters. The character formats (primarily %c; also scan sets %[…]— and %n) are the exception; they don't skip whitespace.

scanf()在尝试解析字符以外的转换之前,该函数会自动跳过前导空格。字符格式(主要是%c; 也扫描集%[…]- 和%n)是例外;他们不会跳过空格。

Use " %c"with a leading blank to skip optional white space. Do not use a trailing blank in a scanf()format string.

" %c"与前导空格一起使用以跳过可选的空格。不要在scanf()格式字符串中使用尾随空格。

Note that this still doesn't consume any trailing whitespace left in the input stream, not even to the end of a line, so beware of that if also using getchar()or fgets()on the same input stream. We're just getting scanf to skip over whitespace beforeconversions, like it does for %dand other non-character conversions.

请注意,这仍然不会消耗输入流中留下的任何尾随空格,甚至不会消耗到行尾,因此如果也在同一输入流上使用getchar()或,请注意这一点fgets()。我们只是让 scanf转换之前跳过空格,就像它为%d和其他非字符转换所做的那样。



Note that non-whitespace "directives" (to use POSIX scanf terminology) other than conversions, like the literal text in scanf("order = %d", &order);doesn't skip whitespace either. The literal orderhas to match the next character to be read.

请注意,除了转换之外的非空白“指令”(使用POSIX scanf 术语),例如文字文本中的文字scanf("order = %d", &order);也不会跳过空白。文字order必须匹配要读取的下一个字符。

So you probably want " order = %d"there if you want to skip a newline from the previous line but still require a literal match on a fixed string, like this question.

因此" order = %d",如果您想从上一行跳过换行符,但仍需要固定字符串上的文字匹配,则您可能想要那里,就像这个 question

回答by Shweta

Use scanf(" %c", &c2);. This will solve your problem.

使用scanf(" %c", &c2);. 这将解决您的问题。

回答by brandizzi

Another option (that I got from here) is to read and discard the newline by using the assignment-supression option. To do that, we just put a format to read a character with an asterisk between %and c:

另一种选择(我从这里得到的)是通过使用assignment-supression option读取和丢弃换行符。为此,我们只需放置一种格式来读取%和之间带有星号的字符c

scanf("%d%*c",&a); // line 1
scanf("%c%*c",&c1); // line 3

scanfwill then read the next char (that is, the newline) but not assign it to any pointer.

scanf然后将读取下一个字符(即换行符)但不将其分配给任何指针。

In the end, however, I would second the FAQ's last option:

然而,最后,我会支持常见问题解答的最后一个选项

Or, depending on your requirements, you could also forget about scanf()/getchar(), use fgets() to get a line of text from the user and parse it yourself.

或者,根据您的要求,您也可以忘记 scanf()/getchar(),使用 fgets() 从用户那里获取一行文本并自行解析。

回答by Jiwon

Use getchar()before calling second scanf().

getchar()在调用 second 之前使用scanf()

scanf("%c", &c1);
getchar();  // <== remove newline
scanf("%c", &c2);