使用printf使输出与输入一样精确?

时间:2014-01-02 09:01:34

标签: c printf

我想编写一个代码,其输出与输入一样精确。考虑一下我是否执行了

scanf("%f", &n);
printf("%f", n);

如果我将1.2作为输入,则应输出1.2,但输出1.200000。它也应该与整数相同,如果我将9作为输入,它应该只输出9,而不是9.00。我有什么方法可以做到这一点吗?

4 个答案:

答案 0 :(得分:1)

OP没有指定如何处理像“9.00”这样的输入。我认为OP希望看到“9.00”打印而不是“9”,因为输入给出了十分之一和百分之一的位置。

首先需要将数字作为字符串读取,以便稍后对其进行精确评估。数量和精度需要单独的变量。建议使用@bgamlath中的结构。

使用sscanf()atof()解析字符串 解析'.'的位置字符串。

int VikasRead(float *value, int *precision) {
  char buf[100];
  *precision = 0;
  if (fgets(buf, sizeof buf, stdin) == NULL) return EOF;
  int end;
  int retval = sscanf(buf, "%f%n", value, &end);
  char * dp = strchr(buf, '.');
  if (dp != NULL && retval == 1) {
    *precision = &buf[end] - dp;
  }
  return retval;
}

int VikasWrite(float value, int precision) {
  int retval;
  if (precision > 1) {
    // Note: printf("%.*f\n", 0, value) is UB.
    retval = printf("%.*f\n", precision - 1, value);  // 1.234
  }
  else if (precision == 0) {;
    retval = printf("%.0f\n", value);  // 123
    }
  else {
    retval = printf("%#.0f\n", value); // 123.
  }
  return retval;
}

void VikasTest(void) {
  float value;
  int precision;
  while (VikasRead(&value, &precision) == 1) {
    VikasWrite(value, precision);
  }
}

1.23e56这样的指数输入使过程复杂化,但方法仍然相同。需要另外查找'e''E'

某些区域设置使用','作为小数点,这使问题更加复杂。

答案 1 :(得分:0)

尝试使用宽度说明符:

printf("%.1f", n);

阅读this了解详情。

但是,请注意:对于floatdouble:由于精度限制,您可能无法将1.2打印为1.2000甚至{{1} },它可能会成为1.2之类的东西。

嗯,这是完全不同的主题,并且在SO上进行了很好的讨论,你可以尝试在互联网上搜索相同的内容,或者在这里搜索。

更新:
对于可变精度,您可以使用1.1996...。更多详情here.

答案 2 :(得分:0)

一种解决方案是按原样存储所有用户输入。使用char指针和gets()scanf("%s", ...)

如果您也想在计算中使用它们,请使用atof进行转换。

另外,您可以使用结构来存储输入表示和数值。

stract Number{
 float val;
 char * representaion; // or only precision if you like.
}

答案 3 :(得分:0)

使用格式说明符%0.7g,因为float的最大精度为7位数

#include <stdio.h>

int numberLenght(float d);

int main(void)
{
    float d;
    printf("input: ");
    scanf("%f", &d);
    printf("your input was: %0.7g\n", d);
    return 0;
}

double使用%0.16gdouble的最大精度为16位数)