【问题标题】:does scanf("%s",ch); skips the leading whitespaces from previous input? [duplicate]scanf("%s",ch);跳过先前输入的前导空格? [复制]
【发布时间】:2021-11-29 17:38:08
【问题描述】:
#include <stdio.h>
#include <string.h>
#include<stdio.h>
int main()
{
   int ch;
   char str;
   scanf("%d", &ch);
   scanf("%c", &str);
   printf("x = %d, str = %c", ch, str);
   return 0;
}

输入:10(输入)
输出:x = 10,str =

在这段代码中 scanf("%d", &ch); 读取一个整数并在缓冲区中留下一个换行符。所以 scanf("%c", &str); 只读取一个换行符。 我明白了。

但是当我运行这段代码时:

#include <stdio.h>
#include <string.h>
#include<stdio.h>
int main()
{
   int ch;
   char str[54];
   scanf("%d", &ch);
   scanf("%s",str);
   printf("x = %d, str = %s", ch, str);
   return 0;
}

输入:10(enter) test
输出:x = 10, str = test

这里似乎 scanf("%s",str); 忽略了缓冲区中的换行符并从控制台读取 test

为什么会这样?

【问题讨论】:

  • 欢迎来到 Stack Overflow。请通过tour 了解 Stack Overflow 的工作原理,并阅读How to Ask 了解如何提高问题的质量。 Please do not upload images of code/errors when asking a question.
  • 它会跳过换行符按设计scanf 转换在它无法转换的第一个字符处停止,通常(但不一定)是空格或换行符,并且该字符保留在输入缓冲区中。 next scanf() 将读取它。格式说明符 %d%s%f 会自动过滤这些前导空白字符,但 %c%[]%n 不会。您可以通过在% 之前添加一个空格来指示scanf 这样做。
  • 大多数scanf 格式字符在解析前 跳过前导空格。并且所有scanf 格式字符在解析后都会留下尾随空格(如换行符\n)。所以通常后面的\n 会被下一个scanf 调用处理。但与其他人不同的是,"%c" 确实 not 跳过前导空格 - 因此它将前一个调用中的尾随 \n 作为它读取的字符。如果你想让"%c" 表现得像其他人一样,你可以输入一个明确的空格,像这样:" %c"

标签: c scanf


【解决方案1】:

"test" 它没有被忽略,问题是您请求的是一个 int(只读数字),然后是一个字符串(读取到 \n 或空格,而不读取那些)。

int ch;
char str[100];
scanf("%d", &ch); // this will read "10" and leave "\ntest\n" on the buffer
scanf("%s", str); // this will read "", so it will ask to the user an input. ("\ntest\n" is still on the buffer)

你想要的是这个:

int ch;
char str[100];
scanf("%d", &ch); // this will read "10" and leave "\ntest\n" on the buffer
scanf("%c", &str[0]); // this will read "\n" and leave "test\n" on the buffer
scanf("%s", str); // this will read "test" and leave "\n" on the buffer

【讨论】:

  • 你的答案是错误的。您的第一个 sn-p 中的 scanf("%s", str); 将跳过输入缓冲区中的所有前导空格...包括上次读取留下的换行符。这是 OP 的第一个代码 sn-p 中的 %c 格式,它不会跳过挂起的换行符。
  • @AdrianMole 你能解释一下吗?
  • 在第一个代码块中,注释// this will read "\n" 不正确。 不可能使用"%s" 格式说明符读取换行符(或“空”字符串),因为它会过滤所有前导空格,并在第一个空格处终止。如果您只是按 Enter 键作为响应,系统将等待您输入至少一个非空白字符。
  • 他们是对的,%s 读到一个空格或 \n(不包括那些)。我可能会想到fgets
  • 编辑仍然不正确。使用%s 无法读取“空字符串”。
【解决方案2】:

为什么会这样?

这就是%sscanf 中指定的功能。在 2018 C 标准中,第 7.21.6.2 条第 7 和第 8 段说:

…转换规范按以下步骤执行:

跳过输入的空白​​字符(由isspace 函数指定),除非该规范包含[cn 说明符。

因此,除了%[%c%n 之外的所有转换都会跳过包含换行符的初始空白字符。

一般来说,scanf 并不是一个功能强大的解析器,它有助于检查输入流中的每个字符。它旨在成为一种便利机制,用于读取简单的数据格式而没有很多严格的约束。跳过空白是其中的一部分。

【讨论】:

  • 非常感谢您的解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-21
  • 1970-01-01
  • 1970-01-01
  • 2015-02-12
  • 2017-08-12
  • 2019-01-01
相关资源
最近更新 更多