【问题标题】:getchar vs scanf: why won't getchar work?getchar 与 scanf:为什么 getchar 不起作用?
【发布时间】:2020-02-05 19:34:40
【问题描述】:

我编写了一个简单的程序来输入一个数字并返回任何值,除以该数字将返回 3 的余数。

我目前正在阅读 K&R,它直到第 7 章才教授 scanf,所以我尝试使用 getchar。它不起作用,但 scanf 可以。我做错了什么?

int main()
{
    int c, i;

    printf("Input an integer: ");
    //c = getchar();
    scanf("%d", &c);

    for (i = 1; i <= 100; i++) {
        if ((i % c) == 3) {
            printf("%d\n", i);
        }
    }
    return 0;
}

可选的附带问题:这里的人们似乎一直建议不要从 K&R 开始。对于初学者来说,什么是更好的选择?

【问题讨论】:

  • 您输入的不是整数。您正在输入单个字符。
  • 那是因为他们做不同的工作。当您使用scanf 输入3 时,您会得到值3,而使用getchar 您会收到字符'3',它在ASCII 编码中是值51
  • getchar 读取单个八位字节,但它返回一个 int 以便它可以返回一个值来指示何时没有读取数据。也就是说,它只能返回一个介于 0 和 255 之间的值。如果你的输入是字符串 '4357',它只会读取 4 并返回本地字符集中的 4 的值。 (例如,52 是一个常用的值)
  • @WeatherVane 谢谢。这解释了我得到的结果。那么有什么办法可以在这里使用getchar并将其转换为值'3'?
  • 此外,它们涵盖了不同的范围:即使为了获得整数进行了一些奇怪的转换,使用 getchar() 最多可以获得 255 的值。使用 scanf 可以获得有符号整数。跨度>

标签: c scanf getchar


【解决方案1】:

这个:

scanf("%d", &c);

正在请求scanf() 从标准输入中读取一个整数值scanf() 函数会根据需要从标准输入读取尽可能多的字符,然后将它们解析为一个整数,将值存储在变量c 中(即&amp;c 指向的地址)。 scanf() 的返回值也传达了正确解析的项目数,因此在这种情况下,您应该检查返回值是否为 1

这个:

c = getchar();

请求getchar() 从标准输入读取单个字符getchar() 函数将尝试读取一个字符,并在成功时将其返回(转换为 int)。如果出现错误或文件结束,将返回特殊整数值EOFgetchar() 返回 int 的事实并不意味着该函数会像 scanf("%d", ...) 那样解析输入。实际上,返回值的类型为 int 只是因为需要将有效字符与 EOF 区分开来。

要了解更多信息,请使用 man 命令参阅 scanfgetchar 的手册页,例如man scanf。查阅手册页对于理解函数的语义很重要。 请务必阅读手册。或者,您可以在线查找:scanf()getchar()


如果您想使用getchar() 扫描单个字符并将其转换为整数,则可以执行以下操作:

#include <stdio.h>  // getchar(), puts()
#include <ctypes.h> // isdigit()

int main(void) }
    int c;

    c = getchar();
    if (c == EOF) {
        puts("Error!");
        return 1;
    }

    if (!isdigit(c)) {
        puts("Character is not a digit!");
        return 1;
    }

    int value = c - '0';
    // value now holds the integer corresponding to the digit that was read from input

    /* ... */

    return 0;
}

注意:c - '0' 有效,因为代表数字的字符在 ASCII 表中具有顺序递增的值(从 0x30 到 0x39)。另见man ascii

【讨论】:

    【解决方案2】:

    getchar 从输入流中读取一个符号并将其作为其内部表示的整数值或EOF 返回。

    所以要读取至少有两位数字的数字,您必须多次调用getchar,然后将符号的表示形式转换为相应的整数。

    getchar相反,scanf 尝试将整数读取为整数,前提是您指定了转换格式 %d 或专门设计用于读取数字的类似格式

    这是一个演示程序,展示了如何使用getchar 实现您的程序。在程序中没有检查用户是否输入了一个太大的数字。您可以自己添加这样的检查。

    #include <stdio.h>
    #include <ctype.h>
    
    int main(void) 
    {
        const unsigned int REMAINDER = 3;
    
        printf( "Input a non-negative integer: " );
    
        unsigned int n = 0;
    
        for ( int c; ( c = getchar() ) != EOF && isdigit( ( unsigned char )c ); )
        {
            const unsigned int Base = 10;
    
            n = Base * n + ( c - '0' );
        }
    
    
        if ( n > REMAINDER )
        {
            const unsigned int N = 100;
            for ( unsigned int i = 0; i < N; i++ )
            {
                if ( ( i + 1 ) % n == REMAINDER ) printf( "%u ", i + 1 );
            }
            putchar( '\n' );
        }
    
        return 0;
    }
    

    程序输出可能看起来像

    Input a non-negative integer: 10
    3 13 23 33 43 53 63 73 83 93 
    

    至于书籍,那么阅读一本你还不熟悉的语言或技术的书籍总是很困难的。

    【讨论】:

    • AFAIK 只有char 类型的值才需要强制转换为unsigned char,可以将c 原样传递给isdigit()
    • @MarcoBonelli 因此,传递的整数可以在函数中被视为负字符值。:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-26
    • 1970-01-01
    • 1970-01-01
    • 2014-01-13
    相关资源
    最近更新 更多