【问题标题】:Scanf char in for is weird [duplicate]for 中的 Scanf char 很奇怪[重复]
【发布时间】:2022-01-07 00:27:32
【问题描述】:
#include <stdio.h>

int main() {
    for (int i = 0; i < 10; i++) {
        printf("0");
        char a[0];
        scanf("%c", a);
    }
}

我编写了这段代码,对于输入中的每个字符,它都会循环额外的时间而无需再次扫描。所以 bash 显示:

0 [我输入'1',然后:]
0011
000111
0000

然后循环终止。就像它将字符保存在 scanf 缓冲区中并在每个循环中一一删除,重新读取它们。但是为什么呢?

【问题讨论】:

  • 您认为char a[0]; 保留了多少内存(即使编译器允许)?接下来,您认为来自scanf("%c", a); 的输入将存储在哪里?
  • 请学习使用空格和(尤其是)缩进来提高代码的可读性。这次我帮你了。
  • 想一想:当你“输入'1'”时,你的确切按键是什么?

标签: c loops scanf


【解决方案1】:

首先,你的代码存在以下严重问题:

您没有为scanf 分配足够的空间来写入字符。将不够大的内存缓冲区传递给scanf 会导致undefined behavior

您应该将char a[0]; 更改为char a[1];,或者更好:只需编写char a; 并将scanf("%c", a); 更改为scanf("%c", &amp;a);

现在,回答您的实际问题:

您没有考虑到换行符 '\n' 也是输入的一部分。您正在注册为附加字符的正是这个字符。

如果你希望换行符被丢弃,那么你可以改变

scanf( "%c", &a );

到:

scanf( " %c", &a );

这将导致scanf 在尝试匹配字符之前丢弃所有空白字符(即空格、制表符、换行符等)。这样,scanf 将永远不会匹配换行符(或任何其他空白字符)。

如果您只想丢弃换行符,而不是空格和其他空白字符,那么您可以改用这些行:

//discard any newline characters
scanf( "%*[\n]" );

//read the actual input
scanf( "%c", &a );

请注意,在上面的代码中,必须有两个单独的scanf 函数调用。你不能像这样组合它们:

//read the actual input
scanf( "%*[\n]%c", &a );

您不能这样做的原因是%[] 转换格式说明符只会匹配非空字符序列。因此,如果没有换行符,匹配将失败。在scanf( "%*[\n]" ); 行中,匹配成功或失败无关紧要,但在scanf( "%*[\n]%c", &amp;a ); 行中,这很重要,因为如果匹配第一个失败,scanf 将不会尝试匹配第二个转换格式说明符.

有关详细信息,请参阅documentation for the function scanf

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-29
    • 1970-01-01
    • 2012-04-07
    相关资源
    最近更新 更多