【问题标题】:using scanf("%d ") with a space after the %d在 %d 之后使用带有空格的 scanf("%d")
【发布时间】:2017-08-19 08:50:26
【问题描述】:

今天在我的 c 课上,我遇到了 scanf() 命令时遇到的麻烦,我们只是在学习指针,我们有一个问题要求我们获取一个数组,并在不使用 [] 的情况下将其反转打印,除了声明 ( int) 数组。当然,这似乎是小菜一碟,但当您不小心写到时却不是:

scanf("%d", arr + i);

你注意到 %d 后面的空格了吗?当然确实花了我一段时间才弄明白,但出于某种原因,这让循环变得疯狂,我希望你们帮助我(和我的老师)弄清楚为什么会发生这种情况。示例:

#include <stdio.h>
#define LEN 10
void arrayInput(int * arr, unsigned int len);
void arrayReverseOutput(int * arr, unsigned int len);

int main(void)
{
    int arr[LEN] = { 0 };
    arrayInput(arr, LEN);
    arrayReverseOutput(arr, LEN);

    system("pause");
    return 0;
}

void arrayInput(int * arr, unsigned int len)
{
    unsigned int i = 0;
    printf("Enter 10 numbers: ");
    for (i = 0; i < len; i++)
    {
        //printf("i = %d \n", i); see what happens when you use this line
        scanf("%d ", arr + i);
    }
}

void arrayReverseOutput(int * arr, unsigned int len)
{
    int i = 0;
    printf("The numbers in reverse order: ");
    for (i = --len; i >= 0; i--)
    {
        printf("%d ", *(arr + i));
    }
}

我真的很想看看那个 scanf 发生了什么……就好像它在第一次运行时需要 2 个输入,但不知何故仍然设法将输入放在数组中的正确位置…… 感谢您抽出宝贵时间阅读本文

【问题讨论】:

  • 你和你的老师有没有阅读scanf的文档?将行为应用于输入?为什么不检查scanf 的结果?使用调试器? 具体是什么不清楚?
  • %d 后面的空格必须匹配。 %d 之前的空格是不必要的。
  • 嗯,不清楚的是 - 代码为什么需要插入另一个输入?它怎么知道它去了数组的哪一部分?因为我的理解是: i = 0:获取第一个和第二个数字 i = 1:获取第三个数字 ... i = 9:获取第 11 个数字,未打印 @Olaf
  • 为什么必须匹配 %d 之后的空格?为什么会这样? @WeatherVane
  • 因为这就是函数的实现方式。您还没有阅读手册页吗?自您发布问题以来,您将花费 25 分钟以上的时间来吸收这组复杂函数的详细信息,并理解为什么必须始终检查函数的返回值:成功扫描的项目数。

标签: c pointers scanf


【解决方案1】:

格式字符串中的空格告诉scanf() 匹配零个或多个空白字符,直到匹配失败。空格 (' ')、换行符 ('\n')、回车 ('\r') 和制表符 ('\t') 属于空白字符。当格式字符串的末尾出现空格时,scanf() 将尝试匹配输入中的空白字符,直到找不到匹配项。但是,scanf() 只能在匹配失败或到达文件末尾时返回。因此,在这样的语句的情况下:

scanf("%d ", arr + i);

scanf() 的调用似乎挂起,贪婪地等待用户的更多输入。每当按下 Enter 键时,都会发送一个换行符并由scanf() 匹配,它仍在等待匹配失败。或文件结束。您可以通过在 Linux 上使用 Ctrl-D 或在 Windows 上使用 Ctrl-C 从键盘发出文件结束信号来转义这样的循环。

用空格终止scanf() 格式字符串几乎总是错误的。换行符 ('\n') 也是一个空白字符,放在格式字符串的末尾时具有相同的效果。

请注意,scanf() 格式字符串中可以有效地使用空格。例如:

int retval = scanf(" %c %c", &c1, &c2);

这里,如果先前的 IO 操作在输入流中留下了换行符(这种情况并不少见),则前导空格指示 scanf() 读取并忽略它。格式字符串中的第二个空格告诉scanf() 在要转换的输入字符之间期望零个或多个空白字符。这允许用户输入带有中间空格的字符。如果没有添加空格,如果用户输入 a b\nc2 最终会保留空格字符的值,并且 b 将留在输入流中以供下一个 IO 操作拾取。另请注意,scanf() 返回成功转换的次数,允许程序检查输入是否符合预期。如果上一行中的retval 不是2,则说明出现问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-18
    • 1970-01-01
    • 2020-12-28
    • 2011-01-10
    相关资源
    最近更新 更多