【问题标题】:Why doesn't getchar() receive any input?为什么 getchar() 不接收任何输入?
【发布时间】:2015-09-05 16:06:12
【问题描述】:

我做了一个程序来看看你叫什么名字,你是男是女,你多大了,我应该叫你夫人,女士,先生,还是只叫你的全名,取决于以前条件。当我选择我的性别为女性并输入名字、姓氏和大于或等于 20 岁的年龄时,我会询问该人是否已婚,但无论出于何种原因,程序都会跳过 getchar,然后完成程序。

代码如下:

#include <stdio.h>
#include <string.h>

int main()
{
    char gender;
    char fName[15]; 
    char lName[15];
    char mar;
    char str[] = "Then I shall call you";
    int age = 0;

    printf("What is your gender (M or F): ");
    gender = getchar();

    printf("First name: ");
    scanf("%s", fName);
    //fgets(fName, 16, stdin);
    //fName[strcspn(fName, "\n")] = 0;

    printf("Last name: ");
    scanf("%s", lName);
    //fgets(lName, 16, stdin);
    //lName[strcspn(lName, "\n")] = 0;

    printf("Age: ");
    scanf("%d", &age);

    puts("");

    if(gender == 'F' || gender == 'f')
    {
        if(age >= 20)
        {   
            printf("Are you married, %s (y or n)?: ", fName);

            //scanf("%c", &mar);
            mar=getchar();

            printf("%c\n", mar); 

            if(mar == 'Y' || mar == 'y')
                printf("%s Mrs. %s.\n", str, lName);

            else if(mar == 'n' && age >= 20|| mar == 'N' && age >= 20)
                printf("%s Ms. %s.\n", str, lName);
        }

        else
            printf("%s %s %s.\n", str, fName, lName);
    }

    else if(gender == 'M' || gender == 'm')
    {
        if(age >= 20)
            printf("%s Mr. %s.\n", str, lName);

        else
            printf("%s %s %s.\n", str, fName,lName);
    }   

    return 0;
}

还有输出:

What is your gender (M or F): F
First name: Jane
Last name: Doe
Age: 25

Are you married, Jane (y or n)?: 

我还有另一个问题是何时使用fgets 而不是scanf 来读取字符串。我听说在读取字符串时通常远离scanf,我尝试了fgets,但输出不是我想要的。

这是我使用fgets 而不是scanf 时的输出:

What is your gender (M or F): M 
First name: Last name: Joe
Age: 23

Then I shall call you Mr. Joe.

输出应该与我使用 scanf 时的状态相同,因此姓氏位于名字下方。

【问题讨论】:

  • 您的问题来自于在scanffgets 中将单个字符getchar() 与多字符输入混合。当你按下 Enter 时,也会产生一个字符,你必须处理它。
  • 使用scanf(" %c", &amp;mar);getchar(); mar=getchar()。问题是因为前一个scanf留下的换行符。
  • 调用系统函数时:scanf(), 1) 始终检查返回值(不是参数值)以确保操作成功。 2) 当使用不自动跳过空格的输入/格式字符串时,在(例如)%s 之前在格式字符串中插入一个空格,这样所有前导空格都会被自动消耗。 3) 使用%s 格式时,始终使用最大长度修饰符(需要比实际输入缓冲区长度小1)即%14s 用于 15 个字符的输入缓冲区。

标签: c arrays string fgets getchar


【解决方案1】:

为什么getchar() 没有收到任何输入?

代码有2个问题:

1) 它得到了上一行剩余的'\n',使用scanf(" %c", &amp;mar);(注意空格)或更好,将所有输入替换为fgets()

2) 它没有报告意外输入。代码应该检测和报告意外输入并处理所有可能的逻辑路径。示例:

    {   
        printf("Are you married, %s (y or n)?: ", fName);
        mar=getchar();
        printf("%c\n", mar); 
        if(mar == 'Y' || mar == 'y')
            printf("%s Mrs. %s.\n", str, lName);
        else if(mar == 'N' || mar == 'n') {
           if (age >= 20)
             printf("%s Ms. %s.\n", str, lName);
           else 
             printf("%s ??? %s.\n", str, lName);
        }
        else { 
          printf("Unexpected input char:'%c' code:%d\n", mar, mar);
        }  
    }

【讨论】:

  • 我使用了scanf(" %c", &amp;mar);,但我宁愿使用fgets,因为它是一个更好的习惯,但是当我尝试这样做时,它给了我警告,说它是来自整数,当它显然是一个强制转换时,有什么方法可以正确地做到这一点?
  • @Asad Mahmood “当我尝试做 it”? 不清楚。
  • @Asad Mahmood 不清楚的是您对fgets() 的使用。使用fgets() 的代码示例会有所帮助。
  • 我尝试用fgets(mar, 1, stdin); 来代替scanf(" %c", &amp;mar); ,当我编译它时,它说“警告:传递'fgets' 的参数1 使指针从整数而不进行强制转换[默认启用] " ,然后我这样写 :fgets(mar, 1, stdin); 并没有发现错误,但是当我编译并运行程序时,我到达询问女性是否已婚的地步,它转到 else 语句并打印 Unexpected输入字符:''代码:0。
  • @Asad Mahmood fgets(mar, 1, stdin) 将不起作用。 1) 第一个参数必须是char *,而不是char。 2)fgets() 想要读取一行数据并形成一个字符串,至少需要一个char s[3]。 3) fgets() 不能很好地与 scanf() 编码。 4) 不幸的是,使用fgets()scanf() 的想法涉及删除所有scant()。建议你在下一个作业中这样做。
【解决方案2】:

问题是scanf。它不会从输入缓冲区中删除换行符,因此getchar 读取的第一件事是\n-char。

要解决这个问题,您可以例如在之前添加一个getchar 调用,这样字符就会从缓冲区中删除,下一个getchar 会读取您的输入。像这样:

...
scanf("%d", &age);
...
getchar();
mar = getchar();
...

【讨论】:

  • 或者他应该完全停止使用scanf(),而不是试图破解其可怕的行为。 OP想逐行读取一条数据;因此他应该使用fgets()。使用fgets() 也更安全,因为它消除了缓冲区溢出错误。
猜你喜欢
  • 1970-01-01
  • 2020-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-13
  • 1970-01-01
  • 1970-01-01
  • 2022-01-20
相关资源
最近更新 更多