开发者

problem reading a file in c

开发者 https://www.devze.com 2023-03-28 13:23 出处:网络
This function is supposed to get a file of vectors. The first line contains the dimension. All other line are in the form of

This function is supposed to get a file of vectors. The first line contains the dimension. All other line are in the form of "P:3,5,2". The letter is P or N and the numbers are coordinates. This function read a line each time it is being invoked and it saves the P/N char and the coordinates into an array of 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]);
    }
}      

when i run it i get an endless loop. the dimension is read correctly but the it prints

LINE 
00.00000010.000000dimentions: 2.000000

endlessly. any ideas why? hope i was clear

EDIT: I've added the calling function:

void fillArray(FILE *sample_p,FILE *separators_p){
    double coordinates[MAX_DIMENSION];
    while (!f开发者_StackOverflow社区eof(sample_p)){
        readSamplesFile(sample_p,coordinates);
    }
}

p.s. fscanf is set to read : and , but to ignore them.


Neither 'P' nor 'N' is a valid double, nor are they ':' or ',', so the fscanf() fails. You should always check the return value from fscanf().

We can also debate whether you'd be better off using fgets() to read a line and sscanf() to parse it. Doing so avoids some issues; it is the way I'd code it automatically.


This code seems to work on the input file:

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

yielding the output:

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):

I'm still not keen on the (mis)use of a floating point dimension, but it works.

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

Note that the fillArray() function, as written, does not do anything with the line of data. There is no checking that the dimension specified is positive and not greater than MAX_DIMENSION (that would go in get_dimension()). It feels cleaner to separate get_dimension() into a separate function than to hide it inside readSampleFile(). There is an argument that readSampleFile() should be renamed readSampleLine() since it does only process one line at a time, not a whole file at a time.

The use of the %n format specifier is a little tricky, but the code needs to know where to resume reading the buffer on the next cycle.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号