【问题标题】:gets() only taking input once in while loopgets() 在 while 循环中只接受一次输入
【发布时间】:2013-01-06 02:32:24
【问题描述】:

我是 C 新手,正在做一些练习,但在 while 循环中遇到了 get() 问题。在搜索中,我认为它可能与 \n 字符有关,但我希望有人能够更彻底地解释这里发生的事情:

这个循环只会运行一次 - 它会再次打印“输入姓氏”到屏幕上,然后在 gets() 有机会第二次接受任何输入之前退出循环:

while (employee_num <= 10)
{
    printf("Enter last name ");
    gets(employee[employee_num].last_name);
    if(strlen(employee[employee_num].last_name) == 0)
        break;
    printf("Enter first name ");
    gets(employee[employee_num].first_name);
    printf("Enter title ");
    gets(employee[employee_num].title);
    printf("Enter salary ");
    scanf("%d", &employee[employee_num].salary);        
    ++employee_num;
}

提前致谢!

【问题讨论】:

  • employee_num 最初设置为多少?
  • 永远不会使用gets。此函数在修复后已损坏,它自己的联机帮助页告诉您不要使用它:永远不要使用gets()。因为在事先不知道数据的情况下不可能知道gets()会读取多少个字符,并且因为gets()会继续存储超过缓冲区末尾的字符,所以使用起来非常危险。它已被用来破坏计算机安全。请改用 fgets()。
  • employee_num 最初设置为 0。我刚刚开始阅读有关 gets() 的问题,但我仍然很好奇为什么它不能正确循环。
  • @user1929959 在输入流上使用 fflush 是未定义的行为,所以不,这将是一个非常糟糕的主意。两个相邻的危险功能不会相互抵消...
  • 为了记录,gets 已从当前标准中的 C 语言中删除。它不再是有效的 C。

标签: c gets


【解决方案1】:

读取薪水后,您的输入缓冲区中会有一个换行符 (\n)。在第二次迭代中,它被选为姓氏。您可以通过在最后一次 scanf 后添加 getchar() 来忽略它:

while (employee_num <= 10) {
    ...
    printf("Enter salary ");
    scanf("%d", &employee[employee_num].salary);        
    ++employee_num;
    getchar();
}

【讨论】:

  • 这行得通。谢谢!当使用 fgets() 代替 get() 时,我假设这个问题不会存在 - 对吗?
  • 是的。不过,您必须去掉输入字符串末尾的额外\n。至于薪水,您可能希望将fgets 放入字符串缓冲区,然后在该缓冲区上使用sscanf()(而不是scanf)。
  • 一般用 fgets 替换gets()!
  • 是否有必要在每次读取更多数据之前刷新正在使用的字符串缓冲区,还是我完全脱离了基础?
  • 在输入“空格”后,scanf() 没有拒绝任何输入吗?
【解决方案2】:

参考skjaidev的回答,

对于gets()换行符 字符(\n)(如果找到)不会复制到字符串中,这就是您出现问题的原因。

另外, 请注意,gets 与 fgets 完全不同:gets 不仅使用 stdin 作为源,而且在结果字符串中不包含结尾 newline 字符,并且不允许为 str 指定最大大小(可以导致缓冲区溢出)。

在程序中使用gets() 被认为是一种不好的做法

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-28
    • 1970-01-01
    • 2021-11-28
    • 2016-08-21
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 2020-11-09
    相关资源
    最近更新 更多