简体   繁体   中英

C - Read in a large number from file

I have a file with large numbers such as -7.47004e-16 and I am trying to read it into a float array using

fscanf(rhs, "%f", &numbers[i]);" 

this is in a while loop. But this does not work when we have a number as the one mentioned above.

Is this not working due to the number being so large? Or is this not working cause of the "e" in the number format?

Could you recommend some ways of doing this properly?

Thanks.

Note: Numbers is a float array and rhs is the file name. The file has one number per line and some numbers are in the same format as above and some numbers are much smaller such as, -1.88493 .

Here is the code:

int main( int argc, char *argv[])
{
    FILE *rhs, *output;
    int niter, n, n1;
    // counters
    int i = 0, j = 0, k, m, p;

    rhs = fopen(argv[1], "r");
    // ab+ opens file for writting and creates the file if need be
    output = fopen(argv[2], "ab+");
    niter = atoi(argv[3]);

    // check if files open up or not, if not exit.
    if((rhs == NULL) || (output == NULL))
    {
        printf("Error Opening files.\n");
        exit(1);
    }

    // read in N
    fscanf(rhs, "%d", &n);

    // initialize n1
    n1 = n + 1;

    // generate array to hold values from rhs file
    long double *numbers = (long double *)malloc(sizeof(long double) * ((n1)*(n1)));
    long double *y = (long double *)malloc(sizeof(long double) * ((n1)*(n1)));
    long double *f = (long double *)malloc(sizeof(long double) * ((n1)*(n1)));
    long double *yp = (long double *)malloc(sizeof(long double) * ((n1)*(n1)));

    // get numbers and store into array
    for(i = 0; i <= n; i++)
    {
        for(j = 0; j <= n; j++)
        {
            fscanf(rhs, "%Lf", &numbers[i]);
            printf("i = %d, number = %Lf\n", i, numbers[i]);
        }
    }

    for(k = 0; k < niter; k++)
    {
        smooth(n, y, yp, f);
    }

    fclose(rhs);
    free(numbers);
    free(y);
    free(f);
    free(yp);

    return 0;

}

An SSCCE ( Short, Self-Contained, Correct Example )

#include <stdio.h>

int main(void)
{
    FILE *rhs = stdin;
    int i = 0;
    float numbers[2];

    if (fscanf(rhs, "%f", &numbers[i]) != 1)
        printf("Failed to convert anything\n");
    else
        printf("Got: %13.6e\n", numbers[i]);
    return 0;
}

Example run:

$ ./flt
-7.47004e-16
Got: -7.470040e-16
$

Note that the code checks that the conversion is successful; you should always do that, and the correct test is as shown — did you get the correct number of successful conversions. You can get a failure to convert without running into EOF, so testing against EOF is incorrect.

That particular number is not too big for an IEEE754 single-precision float so it should be fine.

I'd use double myself just for the added range and precision but that's personal preference.

One thing I'd like to clear up: you stated that rhs was a file name. I'm hoping it's really a file handle returned from fopen , otherwise that would entail a big problem :-)

In addition, I assume you meant the file has one number per line, rather than per file.

By way of example, see the following transcript, which shows an input file, C program using fscanf and the output, to see that this method should work fine:

pax> cat qq.in
    -7.47004e-16
    3.14159
    2.718281828459
    42

pax> cat qq.c
    #include <stdio.h>
    #include <math.h>

    int main (void) {
        float f;
        FILE *fin = fopen ("qq.in", "r");
        while (fscanf (fin, "%f", &f) == 1)
            printf ("    %f %e\n", f, f);
        fclose (fin);
        return 0;
    }

pax> ./qq
    -0.000000 -7.470040e-16
    3.141590 3.141590e+00
    2.718282 2.718282e+00
    42.000000 4.200000e+01

I don't think it's the size limit of float, since it could represent up to 2e−126 , about 1.18 *10e−38 . Perhaps you didn't indicate the precision of float when printing it out?

Try to print it out like this:

printf("%.30f\n", f);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM