【问题标题】:How to determine invalid inputs in c如何确定c中的无效输入
【发布时间】:2014-08-09 20:20:21
【问题描述】:

我想采用浮点输入,但如果用户输入字符输入,它将显示无效输入,我没有在网上找到具体答案。 是怎么做到的?

【问题讨论】:

  • 一个好的开始是在您最喜欢的搜索引擎(又名 Google)上输入 scanf

标签: c input floating-point invalid-characters


【解决方案1】:

虽然scanf 可以安全地解析双精度,但许多编译器已弃用它(有充分的理由),因为它在解析字符串时不安全。此外,如果解析失败,您将在输入缓冲区中留下剩余部分,您必须自己刷新它。

由于这些原因,更喜欢使用像 fgets 这样的函数来检查其提供的缓冲区的长度,然后使用像 strtodsscanf 这样的函数来进行转换。

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    char buf[64];

    /* read */
    if (fgets(buf, sizeof buf, stdin)) {
        /* convert */
        char *err;
        double d = strtod(buf, &err);
        if (*err) {
            puts("entry invalid");
        } else {
            printf("you entered %lf", d);
        }
    }

    return 0;
}

【讨论】:

  • 像 123xyz 这样的输入有效吗?
  • 每个人都在建议scanf,因为scanf 解析double 并不是“天生”不安全的。
  • 好吧,50% 的scanf-建议答案建议scanf,因为scanf 并非天生不安全。
  • @PascalCuoq:是的,很公平:解析一个数字,但我仍然不会使用/教它。我删除了那个位。
  • if (fgets(buf, sizeof buf, stdin)) { double d = strtod(buf, &amp;err); if (*err) { 是一个问题,但在正确的轨道上。 fgets() 通常会得到一个以"\n\0" 结尾的字符串,然后*err 将在其中包含'\n'。也许在if() 之前添加while (isspace(*err)) err++
【解决方案2】:

考虑以下代码片段:

int num;
float val;

num = scanf("%f", &val);
if(num != 1)
{
    printf("You didn't enter a float!\n");
}

scanf 返回它成功扫描的项目数。在您的情况下,您正在尝试扫描一项,float。如果用户没有输入floatscanf 将返回0

注意:如果scanf 失败,用户输入的任何垃圾数据仍将在stdin 流中。您必须手动冲洗它。这是一种这样的方式:

while(((ch = getchar()) != '\n') && (ch != EOF))
    continue;

警告:不要在stdin 上使用fflush

编辑

即使scanf 没有失败,stdin 缓冲区中可能仍有垃圾。例如,如果用户输入:

123xyz

123 将分配给浮点数,x 之后的所有内容都将保留在 stdin 流中。

【讨论】:

  • 像 123xyz 这样的输入有效吗?
  • @SHR 123 有效,但 xyz 无效并保留在 stdin 流中。您需要手动刷新它,因为它可能会意外地用于另一个从 stdin 获取其数据的函数调用。
  • 为什么 fflush 在标准输入上会产生问题?
  • @Jimut fflush 仅用于输出流(例如stdout)。
  • 次要:while(getchar() != '\n') --> EOF 上的无限循环。
猜你喜欢
  • 2017-06-20
  • 1970-01-01
  • 2013-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多