How do I output a result to the number of decimal-points user previously entered (C)?

74 Views Asked by At

I'm trying to output my results to the decimal accuracy the user has input. In other words, if they enter 145, then it outputs to 0 d.p. - if they enter 145.67, it outputs the result to 2 d.p.

I've tried achieving this by trying different things with %.lf but didn't manage to do it so far. Is there a way to do this in C? If so, is there a name for it - so I can learn more about it.

#include <math.h>
#include <stdio.h>

int main() {
  // Using long, double or something else?
  double number, fourthRoot;

  printf("Enter a number: ");
  scanf("%lf", &number);

  fourthRoot = sqrt(sqrt(number));

  printf("4th root of number %lf is %.10lf", number, fourthRoot);

  return 0;
}
2

There are 2 best solutions below

0
chux - Reinstate Monica On

Read user input as a line with fgets() or some scanf("%s",...-like code.

char buf[400];
if (fgets(buf, sizeof buf, stdin)) {

And then process the string. One way is with sscanf()

  int n;
  // Get the number and offset to end of scan
  if (sscanf(buf, "%lf%n", &number, &n) == 1) {
    // Look for '.'
    char *dp = strchr(buf, '.');
    if (dp && dp < buf + n) {
      // decimal point found
      int pre = buf + n - dp - 1;
      printf("%.*f\n", pre, number);  

This works OK but does get fooled if exponential notation used. Additional code could look for the E or e (or P, p with hexadecimal FP notation).

0
William Pursell On

There are a lot of edge cases that you should worry about, but this should get you started:

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

static int
compute_root(const char *s)
{
    char *end;
    double number = strtod(s, &end);
    if( *end ){
        fprintf(stderr, "Invalid input: %s\n", s);
        return 1;
    }
    char *dp = strchr(s, '.');
    int precision = dp ? end - dp - 1: 0;
    char fmt[256];
    snprintf(fmt, sizeof fmt, "4th root of %%s is %%.%dlf\n", precision);
    printf(fmt, s, pow(number, .25));
    return 0;
}

int
main(int argc, char **argv)
{
    int errors = 0;
    char buf[64];
    if( argc > 1 ){
        while( *++argv ){
            errors += compute_root(*argv);
        }
    } else while( scanf("%63s", buf) == 1 ){
        errors += compute_root(buf);
    }
    return errors ? EXIT_FAILURE : EXIT_SUCCESS;
}

As an exercise, consider inputs like 5.345e4. The above code will output with a precision of 5, but you probably want 3. Handling those cases is non-trivial (for certain definitions of "trivial").