在c中读取文件的问题

时间:2011-08-14 12:22:07

标签: c file

这个函数应该得到一个向量文件。第一行 包含维度。所有其他行都是以。的形式出现的 “P:3,5,2”。字母是P或N,数字是坐标。 该函数每次调用时都会读取一行,并保存P / N字符和 坐标为double数组。

void readSamplesFile(FILE *sample_p, double result[])
{
    if (dimension == 0)
    {
    fscanf(sample_p,"%lf",&dimension);
    }
    printf("dimentions: %lf\n",dimension);
    printf("LINE \n");
    int index;
    for (index = 0; index<dimension; index++)
    {
        printf("%d",index);
        fscanf(sample_p,"%lf%*[:,]",&result[index]);
        printf("%lf",result[index]);
    }
}      

当我运行它时,我得到一个无限循环。维度正确读取但是 它打印

LINE 
00.00000010.000000dimentions: 2.000000

无休止。任何想法为什么? 希望我很清楚

编辑: 我添加了调用函数:

void fillArray(FILE *sample_p,FILE *separators_p){
    double coordinates[MAX_DIMENSION];
    while (!feof(sample_p)){
        readSamplesFile(sample_p,coordinates);
    }
}

P.S。 fscanf设置为:和,但忽略它们。

1 个答案:

答案 0 :(得分:1)

'P'和'N'都不是有效的双精度,也不是':'或',',所以fscanf()失败了。您应该始终检查fscanf()的返回值。

我们还可以讨论是否最好使用fgets()来读取一行,sscanf()来解析它。这样做可以避免一些问题;这是我自动编码的方式。


此代码似乎适用于输入文件:

3
P:3,5,2
N:21.12,2.345e6,1.9132e-34

产生输出:

dimension: 3.000000
LINE: P:3,5,2
P:offset=2:0=3(2):1=5(4):2=2(6):
LINE: N:21.12,2.345e6,1.9132e-34
N:offset=2:0=21.12(2):1=2.345e+06(8):2=1.9132e-34(16):

我仍然不热衷于(误)使用浮点dimension,但它确实有效。

#include <stdio.h>

enum { MAX_DIMENSION = 6 };
enum { MAX_BUFFSIZE  = 4096 };

static double dimension = 0.0;

static int get_dimension(FILE *fin)
{
    char buffer[MAX_BUFFSIZE];

    if (fgets(buffer, sizeof(buffer), fin) == 0)
        return -1;
    if (sscanf(buffer, "%lf", &dimension) != 1)
        return -1;
    printf("dimension: %lf\n", dimension);
    return 0;
}

static int readSamplesFile(FILE *sample_p, double result[])
{
    char buffer[MAX_BUFFSIZE];
    if (fgets(buffer, sizeof(buffer), sample_p) == 0)
        return -1;
    printf("LINE: %s", buffer);

    char c;
    int offset;
    if (sscanf(buffer, " %c:%n", &c, &offset) != 1)
        return -1;
    printf("%c:", c);
    printf("offset=%d:", offset);
    for (int index = 0; index < dimension; index++)
    {
        int newoff;
        if (sscanf(&buffer[offset], "%lf%*[:,]%n", &result[index], &newoff) < 1)
            return -1;
        printf("%d=%g(%d):", index, result[index], offset);
        offset += newoff;
    }
    putchar('\n');
    return 0;
}

static void fillArray(FILE *sample_p)
{
    double coordinates[MAX_DIMENSION];
    while (readSamplesFile(sample_p, coordinates) == 0)
        ;
}

int main(void)
{
    if (get_dimension(stdin) == 0)
        fillArray(stdin);
    return 0;
}

请注意,所写的fillArray()函数对数据行没有任何作用。没有检查指定的维度是否为正数且不大于MAX_DIMENSION(将进入get_dimension())。将get_dimension()分隔成单独的函数比将其隐藏在readSampleFile()中更为清晰。有一个论点是readSampleFile()应该重命名为readSampleLine(),因为它一次只处理一行,而不是一次处理整个文件。

使用%n格式说明符有点棘手,但代码需要知道在下一个周期继续读取缓冲区的位置。