0

I'm working with a C(++) program, who needs to read values from a file. Those values can be integers (signed or unsigned) or floating point numbers. At this moment the file only contains decimal numbers (integers), as a sscanf() format specifier %d seems to be sufficient.

However in future the file might contain all kinds of numbers, like positive or negative numbers (integers or floating point numbers) and in latter case, the precision is not known, neather the presence of leading or trailing zeroes, as in following examples:

1
+2
-34
12.5
-13.5
+00014.31000000

Is there a format specifier which can cover all those cases, or am I dreaming?

Thanks

Dominique
  • 16,450
  • 15
  • 56
  • 112
  • 1
    You're dreaming.... use `fgets()`. – Sourav Ghosh May 26 '16 at 10:43
  • Provide the type of the value along with the value, or first check for a floating format, and if it fails, check for an interger. – 2501 May 26 '16 at 10:50
  • for c++ you can use `cin << ` – Rishikesh Raje May 26 '16 at 10:51
  • what data type of variable would this magic specifier store its result in? – M.M May 26 '16 at 10:53
  • Just use a floating-point specifier with a floating-point type. Floating-point types can hold integers after all. – interjay May 26 '16 at 10:53
  • @M.M You could put it into a union with a tag, with a custom parser. – 2501 May 26 '16 at 10:54
  • @2501 useless unless you also have a way of knowing which type to read out... – M.M May 26 '16 at 10:55
  • @M.M Using types and unions usually comes with a tag, otherwise it wouldn't make sense. – 2501 May 26 '16 at 10:56
  • Related: [C - How to check if the number is integer or float?](http://stackoverflow.com/a/20069488/694733) – user694733 May 26 '16 at 11:05
  • As far as the result type is concerned: the idea is to read it as a floating point number. In case the number is an integer, it can be converted afterwards. – Dominique May 26 '16 at 11:44
  • This makes no sense. There is a real number that can be written as `1` or `1.0`. Both ways of writing it are perfectly OK. Incidentally you can also write an integer number as `1` but why should this have any relevance to your work with real numbers? – n. m. could be an AI May 26 '16 at 13:24

1 Answers1

1

I don't think there exists such a magic specifier, because you the type of arguments passed to sscanf() is fixed.

Regardless of the possible loss of precision, integers can be seen as floating point numbers (but no vice versa). So if you don't care whether the input is an integer or a floating point number, simply use fgets(input, BUFFER_SIZE, stdin); followed by scanf(input, "%lf", &dblVal);.

However, if you really care, here is an example on how to deal with them:

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

#define BUFFER_SIZE 80

int main(void)
{
    char *input = malloc(BUFFER_SIZE);
    char *endptr;
    fgets(input, BUFFER_SIZE, stdin);
    input[strcspn(input, "\n")] = '\0';

    long intVal = strtol(input, &endptr, 10);
    if(!*endptr)
    {
        // input is an integer
        printf("%ld", intVal);
    }
    else
    {
        // input is an floating point number
        double dblVal;
        int r, n;
        r = sscanf(input, " %lf%n", &dblVal, &n);
        if(r == 1 && n == strlen(input))
            printf("%g", dblVal);
        else
            puts("Invalid input");
    }
}
nalzok
  • 14,965
  • 21
  • 72
  • 139