简体   繁体   中英

problem reading a file in c

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 (!feof(sample_p)){
        readSamplesFile(sample_p,coordinates);
    }
}

ps 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.

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