【问题标题】:read char from console从控制台读取字符
【发布时间】:2012-01-13 15:44:05
【问题描述】:

我编写控制台应用程序,它为 int 执行几个 scanf 之后,我执行 getchar :

int x,y;
char c;
printf("x:\n");
scanf("%d",&x);
printf("y:\n");
scanf("%d",&y);
c = getchar();

因此我得到c = '\n',尽管输入是:

1
2
a

如何解决这个问题?

【问题讨论】:

  • getchar() 返回int,而不是char
  • @unwind - "从标准输入 (stdin) 返回下一个字符。"-ascii for char

标签: c scanf getchar


【解决方案1】:

这是因为scanf 离开了您在输入流中键入的换行符。试试

do
    c = getchar();
while (isspace(c));

而不是

c = getchar();

【讨论】:

    【解决方案2】:

    scanf 之后调用fflush(stdin); 以丢弃输入缓冲区中scanf 留下的任何不必要的字符(如\r \n)。

    编辑:正如 cmets 中提到的fflush 解决方案可能存在可移植性问题,所以这是我的第二个建议。根本不要使用scanf,而是使用fgetssscanf 的组合来完成这项工作。这是更安全、更简单的方法,因为允许处理错误的输入情况。

    int x,y;
    char c;
    char buffer[80];
    
    printf("x:\n");
    if (NULL == fgets(buffer, 80, stdin) || 1 != sscanf(buffer, "%d", &x))
    {
        printf("wrong input");
    }
    printf("y:\n");
    if (NULL == fgets(buffer, 80, stdin) || 1 != sscanf(buffer, "%d", &y))
    {
        printf("wrong input");
    }
    c = getchar();
    

    【讨论】:

    • -1 fflush(stdin) 未定义。甚至Microsoft/MSDN(定义了这样一个结构)也说(尽管在隐藏位置)它是一个扩展:“// 输入流上的 fflush 是对 C 标准的扩展”。
    • @pmg:没错! (即使我倾向于不时指出它)。这在 SO. 上出现了很多,但它有效 MSDN 支持(您已链接页面),Linux..."For input streams, fflush() discards any buffered data that has been fetched from the underlying file, but has not been consumed by the application...The standards do not specify the behavior for input streams. Most other implementations behave the same as Linux. "...所以它有多糟糕在代码中使用?
    • POSIX.1-2008 page 处的文字略有不同:它根本没有提及应用程序。我根本不喜欢 POSIX.1-2008 的描述。 Linux、Windows 和 POSIX(有所有警告)不足以让我称之为便携。
    • @another.anon.coward:还有,当您可以非常轻松地实现更多实现时,为什么还要心甘情愿地将自己限制在 Linux、Windows 和 POSIX 上?
    • @pmg:关于可移植性,您绝对是对的!但是,如果我要在支持说 Linux 的平台上的实现中限制这个调用,我可以很好地将它与 #ifdef LINUX 之类的宏一起使用(可能就像在可能的情况下使用说 gcc 的 C 扩展)。正如您所提到的,最好坚持标准。感谢您的见解!
    【解决方案3】:

    您可以使用 fflush 函数清除缓冲区中剩余的任何内容,作为先前命令行输入的结果:

    fflush(stdin);
    

    【讨论】:

    • fflush(stdin) 根据 C 标准调用未定义行为,尽管它在某些系统(实现)上已明确定义,但最好避免它以提高可移植性。
    【解决方案4】:

    在您想要的字符之前清理任何空间并忽略剩余字符的方法是

    do {
        c = getchar();
    } while (isspace(c));
    while (getchar() != '\n');
    

    【讨论】:

      【解决方案5】:

      首先,scanf 应为 scanf("%d\n", &x); 或 y。这应该可以解决问题。

      man scanf

      【讨论】:

      • 它没有t work :after I enter 1 it doesnt 写“y:”(见更新的例子),但等待第二个数字并且只有在它写“y:”之后
      猜你喜欢
      • 2013-11-20
      • 2018-06-18
      • 1970-01-01
      • 1970-01-01
      • 2014-12-06
      • 1970-01-01
      • 2011-02-06
      • 1970-01-01
      • 2012-03-19
      相关资源
      最近更新 更多