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.