简体   繁体   English

C-从文件中大量读取

[英]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 我有一个文件较大,例如-7.47004e-16 ,我正在尝试使用以下命令将其读入一个浮点数组

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

this is in a while loop. 这是一个while循环。 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? 还是这不是数字格式中“ e”的工作原因?

Could you recommend some ways of doing this properly? 您能推荐一些正确执行此操作的方法吗?

Thanks. 谢谢。

Note: Numbers is a float array and rhs is the file name. 注意:Numbers是一个浮点数组,rhs是文件名。 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 . 该文件每行有一个数字,有些数字与上述格式相同,有些数字则小得多,例如-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 ) SSCCE( 简短,独立,正确的示例

#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. 您可能会在没有运行EOF的情况下转换失败,因此针对EOF的测试不正确。

That particular number is not too big for an IEEE754 single-precision float so it should be fine. 对于IEEE754单精度浮点数,该特定数字不太大,因此应该没问题。

I'd use double myself just for the added range and precision but that's personal preference. 我只是为了增加范围和精度而double使用,但这是个人喜好。

One thing I'd like to clear up: you stated that rhs was a file name. 我想澄清一件事:您说过rhs是一个文件名。 I'm hoping it's really a file handle returned from fopen , otherwise that would entail a big problem :-) 我希望它实际上是从fopen返回的文件句柄,否则会带来一个大问题:-)

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: 举例来说,请参见以下脚本,该脚本显示了输入文件,使用fscanf C程序和输出,以确保该方法可以正常工作:

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 . 我不认为这是float的大小限制,因为它最多可以表示2e−126 ,大约为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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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