【问题标题】:One digit after the decimal point in input [duplicate]输入中小数点后一位[重复]
【发布时间】:2015-07-27 14:10:27
【问题描述】:

如何在 C 语言中使用 scanf 获取小数点后一位 (0.1) 的浮点数?例如用户可以输入 3.25405... 但在变量中只有 3.2 会被保存。我怎样才能做到这一点 ?这与舍入浮点数不同。

【问题讨论】:

  • 尝试输入0.1并在调试器中查看结果。你可能会感到惊讶。
  • 一般来说,永远不要通过scanf()阅读用户输入。该函数只是没有提供足够的功能来从错误条件中正常恢复,例如格式不匹配等。读取整行输入,然后在内存中解析它(例如通过strtod())。
  • 您可能无法一步完成:scanf(也不是 fscanf 或任何变体,也不是底层的 strtod)函数没有任何规定来执行小数部分的部分解释,它会尝试匹配尽可能多的数字。
  • 一旦你有了这个值,你打算如何使用它?如果您总是使用一个小数点,最好使用定点格式的int
  • 除非你解释为什么它会不同于舍入一个浮点数,否则我会投票结束这个问题作为重复。

标签: c floating-point scanf


【解决方案1】:

使用fgets() 读取并后处理缓冲区。 @DevSolar

char buf[100];
if (fgets(buf, sizeof buf, stdin) == NULL) Handle_EOF();
char *p = strchr(buf,'.');
if (p && isdigit(p[1])) p[2] = 0;
char *endptr;
double y = strtod(buf, &endptr);
...

更好地提醒用户忽略了额外的输入。

if (p && isdigit(p[1])) {
  if (p[2] && p[2] != '\n') puts("Extra input ignored.");
  p[2] = 0;
}
char *endptr;
double y = strtod(buf, &endptr);

【讨论】:

    【解决方案2】:

    我认为你不能一次性做到这一点,因为 scanf 没有像 printf 那样的 'precision' 选项。所以我会这样做:

    int m, n;
    float f;
    scanf("%d.%1d", &m, &n);
    if (m >= 0)
       f=(float)m + ((float)n)/10;
    else
       f=(float)m - ((float)n)/10;
    

    希望对你有帮助。

    我已经根据下面的评论修复了初始解决方案

    【讨论】:

    • 我会使用 double 而不是 float 作为结果,就像 scanf 一样...
    • 1) n & m 反转了吗? 2) whole 部分建议long long。 3) 将符号 f=whole + (whole < 0 ? -1 : 1)*fraction/10.0. 放在一起,因为当 whole < 0 4) 建议 unsigned 分数时上述失败。
    • @chux 是的,m 和 n 颠倒是一个错字。不过我没有意识到标志问题,谢谢指出。
    • 我认为最好使用%d.%1%*d 或其他一些变体,以便跳过被忽略的尾随数字。 (至少,根据最初的请求。)
    【解决方案3】:
    scanf("%3f",&float_var);
    

    当'3'代表3.2的三个字符时('3' + '.' + '2') 很明显,如果你知道你将有一个数字在“。”之前只有一位数字。

    干杯,

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-24
      • 2011-02-18
      • 2021-10-29
      • 2014-07-27
      • 1970-01-01
      • 2015-11-24
      • 2012-03-11
      • 1970-01-01
      相关资源
      最近更新 更多