1

我有一个包含大量数字的文件,例如-7.47004e-16,我正在尝试使用将其读入浮点数组

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

这是在一个while循环中。但是当我们有一个上面提到的数字时,这不起作用。

由于数量太大,这不起作用吗?还是数字格式中的“e”不起作用?

您能推荐一些正确执行此操作的方法吗?

谢谢。

注意:Numbers 是一个浮点数组,rhs 是文件名。该文件每行有一个数字,一些数字与上面的格式相同,一些数字小得多,例如-1.88493.

这是代码:

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;

}

4

3 回答 3

5

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;
}

示例运行:

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

注意代码检查转换是否成功;您应该始终这样做,并且正确的测试如图所示 - 您是否获得了正确数量的成功转换。您可能会在没有遇到 EOF 的情况下转换失败,因此针对 EOF 的测试是不正确的。

于 2013-03-19T09:58:46.187 回答
1

这个特定的数字对于 IEEE754 单精度浮点数来说并不算大,所以应该没问题。

double只是为了增加范围和精度而使用自己,但这是个人喜好。

我想澄清一件事:你说那rhs是一个文件名。我希望它真的是一个从返回的文件句柄fopen,否则会带来一个大问题:-)

另外,我假设您的意思是文件每行有一个数字,而不是每个文件。

举例来说,看下面的脚本,它显示了一个输入文件、C 程序使用fscanf和输出,看看这个方法应该可以正常工作:

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
于 2013-03-19T09:51:50.793 回答
0

我不认为这是 float 的大小限制,因为它最多可以表示2e−126, about 1.18 *10e−38。也许您在打印出来时没有指出浮点数的精度?

尝试像这样打印出来:

printf("%.30f\n", f);
于 2013-03-19T09:55:21.773 回答