fscanf problem

L

learner

I have datafiles like this:
0 1941 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.02 0.00 0.00 1
0 1941 0.00 0.03 0.00 0.03 0.04 0.02 0.00 0.00 0.00 0.00 2
0 1941 0.00 0.00 0.00 0.00 0.52 0.00 0.00 0.17 1.07 0.09 3
0 1941 0.04 0.00 0.00 0.00 0.00 0.62 0.00 0.01 0.00 0.00 4
0 1941 0.00 0.02 0.00 0.00 0.00 0.22 0.00 0.00 0.00 0.16 5
0 1941 0.00 0.00 0.00 0.00 0.09 0.04 0.00 0.00 0.00 0.00 6
0 1941 0.00 0.83 0.00 0.00 0.00 0.00 0.00 0.00 0.22 0.03 7
0 1941 0.31 0.00 0.00 0.00 0.00 0.00 0.03 0.00 0.00 0.00 8
0 1941 0.00 0.48 0.38 0.07 0.00 0.12 0.00 0.00 0.00 0.00 9
0 1941 0.00 0.00 0.01 0.00 0.00 0.00 0.00 0.37 0.00 0.00 10
0 1941 1.13 0.01 0.00 0.00 0.00 0.00 0.00 0.07 0.00 0.00 11
0 1941 0.00 0.16 0.00 0.00 0.00 0.23 0.00 0.00 0.00 0.00 12
0 1941 0.01 0.10 0.00 0.00 0.00 0.00 0.00 0.00 0.13 0.00 13
0 1941 0.00 1.18 0.38 0.73 0.00 0.16 0.00 0.00 0.00 0.00 14
0 1941 0.00 0.00 0.00 0.00 0.01 0.00 0.00 0.30 0.00 0.00 15
0 1941 0.56 0.02 0.00 0.00 0.06 0.00 0.31 0.00 0.00 0.00 16
0 1941 0.00 0.00 0.00 0.34 0.29 0.32 0.00 0.00 0.00 0.00 17
0 1941 0.00 0.00 0.00 1.06 0.67 0.00 0.00 0.00 0.00 1.41 18
0 1941 0.00 0.00 0.00 0.00 0.52 0.00 0.00 0.00 0.00 0.29 19
0 1941 0.00 0.20 0.44 0.01 0.00 0.00 0.00 0.05 0.32 0.00 20
0 1941 0.00 0.00 0.00 0.00 0.75 0.00 0.00 1.10 0.00 1.87 21
0 1941 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.01 0.00 22
0 1941 0.00 0.00 0.00 0.00 0.00 0.00 0.28 0.78 0.00 0.00 23
0 1941 0.00 0.35 0.00 0.32 0.00 0.00 0.50 0.00 0.00 0.00 24
0 1941 0.00 0.00 0.00 0.00 1.38 0.25 1.16 0.00 0.00 0.00 25
0 1941 0.32 0.00 0.00 0.00 0.00 0.25 0.04 0.00 0.00 0.00 26
0 1941 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 27
0 1941 0.16 0.22 0.00 0.00 0.16 0.00 0.00 0.00 0.00 0.00 28
0 1941 0.00 0.00 1.24 0.00 0.10 0.07 0.02 0.02 0.02 0.00 29
0 1941 0.25 0.04 0.56 0.27 0.00 0.00 0.00 0.00 0.00 0.00 30
0 1941 0.00 0.00 0.00 0.00 0.00 0.01 0.00 0.00 0.00 0.01 31
0 1941 0.51 0.01 0.46 0.00 0.00 0.92 0.00 0.00 0.00 0.00 32
0 1941 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.24 0.00 0.00 33
0 1941 0.00 0.00 0.43 0.19 0.00 0.00 0.00 0.00 0.00 0.00 34
0 1941 0.00 0.00 0.05 0.12 0.38 0.26 0.01 0.00 0.00 0.00 35
0 1941 0.00 0.01 0.71 0.00 0.00 0.20 0.13 0.62 0.90 0.00 36
0 1941 0.00 0.01 0.02 0.04 0.00 0.00 37
0 1942 0.00 0.00 0.00 0.00 0.02 0.03 0.00 0.00 0.00 0.00 1
0 1942 0.00 0.02 0.00 0.00 0.08 0.00 0.00 0.00 0.00 0.00 2
0 1942 0.00 0.00 0.00 0.00 0.10 0.00 0.00 0.83 0.90 0.18 3
0 1942 0.00 0.00 0.00 0.00 0.31 0.00 0.00 0.00 0.00 0.00 4
0 1942 0.31 0.00 0.00 0.00 0.01 0.00 0.00 0.00 0.00 0.00 5
0 1942 0.00 0.00 0.00 0.58 0.00 0.00 0.00 0.00 0.12 0.00 6
0 1942 0.00 0.00 0.00 0.00 0.04 0.31 0.00 0.00 0.00 0.00 7
0 1942 0.00 0.13 0.03 0.17 0.37 0.00 0.00 0.00 0.00 0.00 8
0 1942 0.00 1.03 0.00 0.00 0.21 0.00 0.00 0.09 0.05 0.00 9
0 1942 0.00 0.00 0.83 0.00 0.00 0.00 0.00 0.00 0.00 0.25 10
0 1942 0.54 0.00 1.24 0.05 0.01 0.46 0.32 0.10 0.07 0.00 11
0 1942 0.00 0.00 0.04 0.00 0.00 0.00 0.00 0.00 0.22 0.00 12
0 1942 0.00 0.00 0.01 0.00 0.00 0.00 0.04 0.00 0.00 0.02 13
0 1942 0.00 0.00 0.48 0.00 0.00 0.00 0.00 0.00 0.00 0.00 14
0 1942 0.00 0.00 0.00 0.00 0.63 0.01 0.46 0.36 0.84 0.10 15
0 1942 1.00 0.16 0.00 0.00 0.00 0.00 0.00 0.04 0.00 0.00 16
0 1942 1.04 0.24 0.00 0.00 0.00 0.00 0.00 0.13 0.00 0.00 17
0 1942 0.00 0.05 0.00 0.00 0.00 0.00 0.00 0.11 0.04 0.06 18
0 1942 0.00 1.19 0.00 0.00 0.00 0.00 0.00 0.00 0.53 0.29 19
0 1942 0.28 0.06 0.00 0.00 0.03 0.21 0.30 0.00 0.76 0.00 20
0 1942 0.00 0.00 0.00 0.00 0.30 2.11 0.00 0.00 0.01 0.00 21
0 1942 0.09 0.00 0.00 0.00 0.00 0.00 0.77 0.00 0.40 0.00 22
0 1942 0.00 0.00 0.66 0.10 0.00 0.01 0.00 0.00 0.00 0.00 23
0 1942 0.00 1.10 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 24
0 1942 0.00 0.00 0.00 0.00 0.40 0.00 0.00 0.00 0.00 0.00 25
0 1942 0.00 0.00 0.00 0.00 0.00 0.32 0.01 0.00 0.00 0.91 26
0 1942 0.01 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.98 27
0 1942 0.38 0.01 0.83 0.27 0.00 0.01 0.23 0.00 0.47 0.20 28
0 1942 0.00 0.00 0.30 0.00 0.00 0.04 0.11 0.00 0.00 0.00 29
0 1942 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 30
0 1942 0.00 0.00 0.49 1.84 1.87 0.00 0.00 0.00 0.28 0.11 31
0 1942 0.02 0.00 0.00 0.00 0.00 0.00 0.01 0.77 0.00 0.00 32
0 1942 0.00 0.00 0.21 0.66 0.03 0.18 0.32 0.00 0.00 0.00 33
0 1942 0.00 0.00 0.00 0.01 0.02 0.68 0.13 0.00 0.00 0.00 34
0 1942 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.10 35
0 1942 0.00 0.00 0.00 0.00 0.86 0.00 0.24 0.22 0.00 0.00 36
0 1942 0.00 0.00 0.00 0.00 0.00 0.00 37



For each year, it has 37 lines of numbers and each line contains 10
actual data points, then it starts over for the next year in exactly
the same format. I have a problem in my original bigger program in
fscanf to get these numbers. So I condensed it to this:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

main(int argc, char *argv[])
{
int i,yr;
long linenumber;
char filename[200];
char *sfname1,*sfname2,*sfname3;
FILE *fp;
FILE *otf;
FILE *fptest;
char dump[80];
char *line;
int dum,year,l;
float f1,f2,f3,f4,f5,f6,f7,f8,f9,f10, sum_mon;

i=0;yr=1941;linenumber=0;sum_mon = 0;
line = malloc(80); assert(line !=NULL); strcpy(line,"");
strcpy(filename,argv[1]);

fp = fopen(filename,"r"); if(!fp) printf("file open problems\n");
fptest = fopen("z.pcp.test","w+"); if(!fptest) printf("file open
problems\n");
for (yr=0; yr<2; yr++) { // year loop
for (i=1;i<=12; i++) {
//fgets(line, 80, fp);

fscanf(fp,"%d%d%f%f%f%f%f%f%f%f%f%f%d",&dum,&year,&f1,&f2,&f3,&f4,&f5,&f6,&f7,&f8,&f9,&f10,&l);
}
//line 13

fscanf(fp,"%d%d%f%f%f%f%f%f%f%f%f%f%d",&dum,&year,&f1,&f2,&f3,&f4,&f5,&f6,&f7,&f8,&f9,&f10,&l);

printf("%5d%5d%5.2f%5.2f%5.2f%5.2f%5.2f%5.2f%5.2f%5.2f%5.2f%5.2f%10d\n",dum,year,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,l);
for (i=14;i<=36; i++) {
//fgets(line, 80, fp);

fscanf(fp,"%d%d%f%f%f%f%f%f%f%f%f%f%d",&dum,&year,&f1,&f2,&f3,&f4,&f5,&f6,&f7,&f8,&f9,&f10,&l);
}
fgets(line,80,fp);
}
fclose (fp);
}

The purpose is to just see why fscanf can't get the well formatted data
correctly in my original program. You can save the data file by c-n-p
the data
above in a file in the same directory as the above program and then at
prompt:
a.out filename to run the program. You will notice that first of all, I
want print out every line 13 in each year, but it print out line 14.
Secondly, it kept printing the last line in the first year! I am really
puzzled. Please help. I 've tried some other things already, I know I
can getline (char by char etc) or sscanf I am still not sure why the
above wouldn't work.

thanks.
 
M

Michael Mair

learner said:
I have datafiles like this:
0 1941 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.02 0.00 0.00 1
0 1941 0.00 0.03 0.00 0.03 0.04 0.02 0.00 0.00 0.00 0.00 2
0 1941 0.00 0.00 0.00 0.00 0.52 0.00 0.00 0.17 1.07 0.09 3
0 1941 0.04 0.00 0.00 0.00 0.00 0.62 0.00 0.01 0.00 0.00 4
0 1941 0.00 0.02 0.00 0.00 0.00 0.22 0.00 0.00 0.00 0.16 5
0 1941 0.00 0.00 0.00 0.00 0.09 0.04 0.00 0.00 0.00 0.00 6
0 1941 0.00 0.83 0.00 0.00 0.00 0.00 0.00 0.00 0.22 0.03 7
0 1941 0.31 0.00 0.00 0.00 0.00 0.00 0.03 0.00 0.00 0.00 8
0 1941 0.00 0.48 0.38 0.07 0.00 0.12 0.00 0.00 0.00 0.00 9
0 1941 0.00 0.00 0.01 0.00 0.00 0.00 0.00 0.37 0.00 0.00 10
0 1941 1.13 0.01 0.00 0.00 0.00 0.00 0.00 0.07 0.00 0.00 11
0 1941 0.00 0.16 0.00 0.00 0.00 0.23 0.00 0.00 0.00 0.00 12
0 1941 0.01 0.10 0.00 0.00 0.00 0.00 0.00 0.00 0.13 0.00 13
0 1941 0.00 1.18 0.38 0.73 0.00 0.16 0.00 0.00 0.00 0.00 14
0 1941 0.00 0.00 0.00 0.00 0.01 0.00 0.00 0.30 0.00 0.00 15
0 1941 0.56 0.02 0.00 0.00 0.06 0.00 0.31 0.00 0.00 0.00 16
0 1941 0.00 0.00 0.00 0.34 0.29 0.32 0.00 0.00 0.00 0.00 17
0 1941 0.00 0.00 0.00 1.06 0.67 0.00 0.00 0.00 0.00 1.41 18
0 1941 0.00 0.00 0.00 0.00 0.52 0.00 0.00 0.00 0.00 0.29 19
0 1941 0.00 0.20 0.44 0.01 0.00 0.00 0.00 0.05 0.32 0.00 20
0 1941 0.00 0.00 0.00 0.00 0.75 0.00 0.00 1.10 0.00 1.87 21
0 1941 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.01 0.00 22
0 1941 0.00 0.00 0.00 0.00 0.00 0.00 0.28 0.78 0.00 0.00 23
0 1941 0.00 0.35 0.00 0.32 0.00 0.00 0.50 0.00 0.00 0.00 24
0 1941 0.00 0.00 0.00 0.00 1.38 0.25 1.16 0.00 0.00 0.00 25
0 1941 0.32 0.00 0.00 0.00 0.00 0.25 0.04 0.00 0.00 0.00 26
0 1941 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 27
0 1941 0.16 0.22 0.00 0.00 0.16 0.00 0.00 0.00 0.00 0.00 28
0 1941 0.00 0.00 1.24 0.00 0.10 0.07 0.02 0.02 0.02 0.00 29
0 1941 0.25 0.04 0.56 0.27 0.00 0.00 0.00 0.00 0.00 0.00 30
0 1941 0.00 0.00 0.00 0.00 0.00 0.01 0.00 0.00 0.00 0.01 31
0 1941 0.51 0.01 0.46 0.00 0.00 0.92 0.00 0.00 0.00 0.00 32
0 1941 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.24 0.00 0.00 33
0 1941 0.00 0.00 0.43 0.19 0.00 0.00 0.00 0.00 0.00 0.00 34
0 1941 0.00 0.00 0.05 0.12 0.38 0.26 0.01 0.00 0.00 0.00 35
0 1941 0.00 0.01 0.71 0.00 0.00 0.20 0.13 0.62 0.90 0.00 36
0 1941 0.00 0.01 0.02 0.04 0.00 0.00 37
0 1942 0.00 0.00 0.00 0.00 0.02 0.03 0.00 0.00 0.00 0.00 1
0 1942 0.00 0.02 0.00 0.00 0.08 0.00 0.00 0.00 0.00 0.00 2
0 1942 0.00 0.00 0.00 0.00 0.10 0.00 0.00 0.83 0.90 0.18 3
0 1942 0.00 0.00 0.00 0.00 0.31 0.00 0.00 0.00 0.00 0.00 4
0 1942 0.31 0.00 0.00 0.00 0.01 0.00 0.00 0.00 0.00 0.00 5
0 1942 0.00 0.00 0.00 0.58 0.00 0.00 0.00 0.00 0.12 0.00 6
0 1942 0.00 0.00 0.00 0.00 0.04 0.31 0.00 0.00 0.00 0.00 7
0 1942 0.00 0.13 0.03 0.17 0.37 0.00 0.00 0.00 0.00 0.00 8
0 1942 0.00 1.03 0.00 0.00 0.21 0.00 0.00 0.09 0.05 0.00 9
0 1942 0.00 0.00 0.83 0.00 0.00 0.00 0.00 0.00 0.00 0.25 10
0 1942 0.54 0.00 1.24 0.05 0.01 0.46 0.32 0.10 0.07 0.00 11
0 1942 0.00 0.00 0.04 0.00 0.00 0.00 0.00 0.00 0.22 0.00 12
0 1942 0.00 0.00 0.01 0.00 0.00 0.00 0.04 0.00 0.00 0.02 13
0 1942 0.00 0.00 0.48 0.00 0.00 0.00 0.00 0.00 0.00 0.00 14
0 1942 0.00 0.00 0.00 0.00 0.63 0.01 0.46 0.36 0.84 0.10 15
0 1942 1.00 0.16 0.00 0.00 0.00 0.00 0.00 0.04 0.00 0.00 16
0 1942 1.04 0.24 0.00 0.00 0.00 0.00 0.00 0.13 0.00 0.00 17
0 1942 0.00 0.05 0.00 0.00 0.00 0.00 0.00 0.11 0.04 0.06 18
0 1942 0.00 1.19 0.00 0.00 0.00 0.00 0.00 0.00 0.53 0.29 19
0 1942 0.28 0.06 0.00 0.00 0.03 0.21 0.30 0.00 0.76 0.00 20
0 1942 0.00 0.00 0.00 0.00 0.30 2.11 0.00 0.00 0.01 0.00 21
0 1942 0.09 0.00 0.00 0.00 0.00 0.00 0.77 0.00 0.40 0.00 22
0 1942 0.00 0.00 0.66 0.10 0.00 0.01 0.00 0.00 0.00 0.00 23
0 1942 0.00 1.10 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 24
0 1942 0.00 0.00 0.00 0.00 0.40 0.00 0.00 0.00 0.00 0.00 25
0 1942 0.00 0.00 0.00 0.00 0.00 0.32 0.01 0.00 0.00 0.91 26
0 1942 0.01 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.98 27
0 1942 0.38 0.01 0.83 0.27 0.00 0.01 0.23 0.00 0.47 0.20 28
0 1942 0.00 0.00 0.30 0.00 0.00 0.04 0.11 0.00 0.00 0.00 29
0 1942 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 30
0 1942 0.00 0.00 0.49 1.84 1.87 0.00 0.00 0.00 0.28 0.11 31
0 1942 0.02 0.00 0.00 0.00 0.00 0.00 0.01 0.77 0.00 0.00 32
0 1942 0.00 0.00 0.21 0.66 0.03 0.18 0.32 0.00 0.00 0.00 33
0 1942 0.00 0.00 0.00 0.01 0.02 0.68 0.13 0.00 0.00 0.00 34
0 1942 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.10 35
0 1942 0.00 0.00 0.00 0.00 0.86 0.00 0.24 0.22 0.00 0.00 36
0 1942 0.00 0.00 0.00 0.00 0.00 0.00 37



For each year, it has 37 lines of numbers and each line contains 10
actual data points, then it starts over for the next year in exactly
the same format. I have a problem in my original bigger program in
fscanf to get these numbers. So I condensed it to this:

Condense is hardly the right word. One could bring down the format
for finding errors down to 1 integer followed by 2 floating point
numbers followed by another integer (times 2 lines) followed by a
line with 1 integer, 1 float, 1 integer.
Once repeated.
This could serve to make your *scanf() calls more readable.
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

main(int argc, char *argv[])
Better:
int main (int argc, char **argv)
{
int i,yr;
long linenumber;
char filename[200];
char *sfname1,*sfname2,*sfname3;
unused

FILE *fp;
FILE *otf;
unused

FILE *fptest;
char dump[80];
unused

char *line;
int dum,year,l;
float f1,f2,f3,f4,f5,f6,f7,f8,f9,f10, sum_mon;

This looks like a candidate for an array.
i=0;yr=1941;linenumber=0;sum_mon = 0;
line = malloc(80); assert(line !=NULL); strcpy(line,"");

Bad idea: Use of magic numbers (10 floats, buffer of 80, start
at 1941).
Bad idea: do not use assert to catch usual errors. This is
for debugging purposes only. If you really need the assert()
during debugging, at least follow through with some error
handling for productive use of your program.
Note that the strcpy() is completely unnecessary.
strcpy(filename,argv[1]);

Left out checking whether argc >= 2.
You do not need filename if you do not want to change the string
pointed to by argv[1]; use argv[1] instead.
fp = fopen(filename,"r"); if(!fp) printf("file open problems\n");
fptest = fopen("z.pcp.test","w+"); if(!fptest) printf("file open
problems\n");

Note: Error messages should go to stderr, i.e.
fprintf(stderr, ....);
This is not real error handling and will get you into
trouble.
for (yr=0; yr<2; yr++) { // year loop
for (i=1;i<=12; i++) {
//fgets(line, 80, fp);

fscanf(fp,"%d%d%f%f%f%f%f%f%f%f%f%f%d",&dum,&year,&f1,&f2,&f3,&f4,&f5,&f6,&f7,&f8,&f9,&f10,&l);

Note: If you are not interested in something fscanf() has to scan, you
can scan and discard it by using "%*R" where R is to be replaced by the
appropriate format/scanset specifier.

Always use the return value of *scanf() to make sure that reading
was successful. fscanf() leaves whitespace trash unscanned.
Consider using fgets() + sscanf() or better yet fgets() plus
specialized functions like strtol()/strtod() if you are not
completely sure what you are doing.

Once again: f1..f10 are candidates for an array and a loop to get
the array values.
}
//line 13

fscanf(fp,"%d%d%f%f%f%f%f%f%f%f%f%f%d",&dum,&year,&f1,&f2,&f3,&f4,&f5,&f6,&f7,&f8,&f9,&f10,&l);

printf("%5d%5d%5.2f%5.2f%5.2f%5.2f%5.2f%5.2f%5.2f%5.2f%5.2f%5.2f%10d\n",dum,year,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,l);
for (i=14;i<=36; i++) {
//fgets(line, 80, fp);

fscanf(fp,"%d%d%f%f%f%f%f%f%f%f%f%f%d",&dum,&year,&f1,&f2,&f3,&f4,&f5,&f6,&f7,&f8,&f9,&f10,&l);
}
fgets(line,80,fp);

You do not check the return value of fgets().
}
fclose (fp);

For extra brownie points:
return 0;
}

The purpose is to just see why fscanf can't get the well formatted data
correctly in my original program. You can save the data file by c-n-p
the data
above in a file in the same directory as the above program and then at
prompt:
a.out filename to run the program. You will notice that first of all, I
want print out every line 13 in each year, but it print out line 14.
Secondly, it kept printing the last line in the first year! I am really
puzzled. Please help. I 've tried some other things already, I know I
can getline (char by char etc) or sscanf I am still not sure why the
above wouldn't work.

Hint: Boil it down as suggested above, i.e. provide a _true_
minimal example.
Read the description of fscanf() thorougly.
Mind the difference between scanning for "\n%d %d %f....%f %d" and
"%d %d %f....%f %d\n" (where '\n' just should give you an idea about
the special whitespace meant).


Cheers
Michael
 
L

learner

Hi, I 've cleaned up a little bit of the code I post according to
suggestion and I 've tried some variation with position of \n in
*scanf. It failed at the first attempt. I 've got the thing work using
gets and pick-it-apart approach, but still would like to get it work
with fscanf, please help. Here is the new seg of code (the input file
is as posted in my first post, thanks):

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

int main(int argc, char *argv[])
{
int i,yr,f;
FILE *fp;

char *line;
int dum,year,l;
float f1,f2,f3,f4,f5,f6,f7,f8,f9,f10;

i=0;yr=1941;
line = malloc(100);
if(line ==NULL)
{fprintf(stderr,"line malloc fail\n"); exit(-1);}

if (argc <2)
{fprintf(stderr,"Need a filename as commandline input\n"); exit(-1);}

fp = fopen(argv[1],"r");
if(!fp)
{ fprintf(stderr,"Input file open failed\n"); exit(-2); }
for (yr=0; yr<2; yr++) { // year loop
for (i=1;i<=12; i++) {

f=fscanf(fp,"%*d%*d%*f%*f%*f%*f%*f%*f%*f%*f%*f%*f%*d\n",&dum,&year,&f1,&f2,&f3,&f4,&f5,&f6,&f7,&f8,&f9,&f10,&l);
//f=fscanf(fp,"%*d%*d%*f%*f%*f%*f%*f%*f%*f%*f%*f%*f%*d");
if (f<13)
{fprintf(stderr,"Read in: %d, Scan first section failed\n",f);
exit(-3);}
}
//line 13
f=
fscanf(fp,"%d%d%f%f%f%f%f%f%f%f%f%f%d",&dum,&year,&f1,&f2,&f3,&f4,&f5,&f6,&f7,&f8,&f9,&f10,&l);
if (f<13)
{ fprintf(stderr,"Read in: %d, Scan line 13 failed\n",f);
exit(-3);}


printf("%5d%5d%5.2f%5.2f%5.2f%5.2f%5.2f%5.2f%5.2f%5.2f%5.2f%5.2f%10d\n",dum,year,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,l);
for (i=14;i<=36; i++) {
//fgets(line, 80, fp);


f=fscanf(fp,"%d%d%f%f%f%f%f%f%f%f%f%f%d",&dum,&year,&f1,&f2,&f3,&f4,&f5,&f6,&f7,&f8,&f9,&f10,&l);
if (f<13)
{ fprintf(stderr,"Read in: %d, Scan section 3 failed\n",f);
exit(-4);}
}
fgets(line,80,fp);
if (strlen(line) == 0)
{ fprintf(stderr,"fgets line failed\n"); exit(-5); }
}
fclose (fp);
return 0;
}
 
M

Michael Mair

Please quote a minimum of context s.th. everyone knows what you
are replying to -- it is perfectly possible for someone to read
your reply before ever seeing what I wrote (if ever).
You are welcome snip what is not germane to your reply, of course.
Hi, I 've cleaned up a little bit of the code I post according to
suggestion and I 've tried some variation with position of \n in
*scanf.

Well, some kind of whitespace has to go at the _beginning_ of the line
in the case of fscanf().
It failed at the first attempt. I 've got the thing work using
gets and pick-it-apart approach, but still would like to get it work
with fscanf, please help. Here is the new seg of code (the input file
is as posted in my first post, thanks):

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

int main(int argc, char *argv[])
{
int i,yr,f;
FILE *fp;

char *line;
int dum,year,l;
float f1,f2,f3,f4,f5,f6,f7,f8,f9,f10;

i=0;yr=1941;

Unnecessary initialisation.
line = malloc(100);
if(line ==NULL)
{fprintf(stderr,"line malloc fail\n"); exit(-1);}

Only 0, EXIT_SUCCESS and EXIT_FAILURE are portable arguments to exit().
Everything else may work on your computer at a certain for a certain
version of a certain compiler but not everywhere.
if (argc <2)
{fprintf(stderr,"Need a filename as commandline input\n"); exit(-1);}

Check this one first -- everything else follows or not.
You forgot to free your memory before exit.
fp = fopen(argv[1],"r");
if(!fp)
{ fprintf(stderr,"Input file open failed\n"); exit(-2); }

You forgot to free your memory before exit.
for (yr=0; yr<2; yr++) { // year loop
for (i=1;i<=12; i++) {

f=fscanf(fp,"%*d%*d%*f%*f%*f%*f%*f%*f%*f%*f%*f%*f%*d\n",&dum,&year,&f1,&f2,&f3,&f4,&f5,&f6,&f7,&f8,&f9,&f10,&l);

As I wrote, * is used to scan but discard something.
So you are essentially throwing away the content of your line
and come up with scanned input object count of 0.
//f=fscanf(fp,"%*d%*d%*f%*f%*f%*f%*f%*f%*f%*f%*f%*f%*d");
if (f<13)
{fprintf(stderr,"Read in: %d, Scan first section failed\n",f);
exit(-3);}
}
//line 13
f=
fscanf(fp,"%d%d%f%f%f%f%f%f%f%f%f%f%d",&dum,&year,&f1,&f2,&f3,&f4,&f5,&f6,&f7,&f8,&f9,&f10,&l);
if (f<13)
{ fprintf(stderr,"Read in: %d, Scan line 13 failed\n",f);
exit(-3);}


printf("%5d%5d%5.2f%5.2f%5.2f%5.2f%5.2f%5.2f%5.2f%5.2f%5.2f%5.2f%10d\n",dum,year,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,l);
for (i=14;i<=36; i++) {
//fgets(line, 80, fp);


f=fscanf(fp,"%d%d%f%f%f%f%f%f%f%f%f%f%d",&dum,&year,&f1,&f2,&f3,&f4,&f5,&f6,&f7,&f8,&f9,&f10,&l);
if (f<13)
{ fprintf(stderr,"Read in: %d, Scan section 3 failed\n",f);
exit(-4);}
}
fgets(line,80,fp);

Once again: check the return value of fgets, e.g. in combination
with the following check:
if ( !fgets(....) || strlen(line) == 0 )
if (strlen(line) == 0)
{ fprintf(stderr,"fgets line failed\n"); exit(-5); }
}
fclose (fp);

You forgot to free your allocated memory:
free(line);
return 0;
}

Here is a slightly different version incorporating all the
stuff I originally suggested.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFSIZE 100
#define FLOATS_PER_LINE 10
#define FLOATS_PER_YEAR 366
#define NUMYEARS 2

int main (int argc, char **argv)
{
int i, j, k, yr;
int year, l;
float f[FLOATS_PER_LINE]; /* Went over to an array */
FILE *fp;
char *line; /* No longer necessary but I drag it around to
** show you proper handling of the freeing */

/* Basic check; without that, we need not start everything else */
if (argc < 2) {
fprintf(stderr, "Need a filename as commandline input\n");
exit(EXIT_FAILURE);
}

/* Get buffer and open file */
line = malloc(BUFSIZE);
if (line ==NULL) {
fprintf(stderr, "Line %d: line malloc fail\n", __LINE__);
exit(EXIT_FAILURE);
}

fp = fopen(argv[1],"r");
if (!fp) {
fprintf(stderr, "Input file open failed for %s\n", argv[1]);
free(line); /* Now: Free before you exit. */
exit(EXIT_FAILURE);
}

for (j=0; j<FLOATS_PER_LINE; j++)
f[j] = 0.0F;

/* Scan through all years */
for (yr=0; yr<NUMYEARS; yr++) {
/* Go through 37 lines, in this case, k is used to keep track of
** the number of scanned floats per year */
for (i=0, k=0;
i<(FLOATS_PER_YEAR+FLOATS_PER_LINE-1)/FLOATS_PER_LINE;
i++)
{
/* The first integer is read but discarded, the second
** goes into year */
if (1 != fscanf(fp, "\n%*d %d", &year)) {
fputs("Problems reading lead-in of line\n", stderr);
}
for (j=0; j<FLOATS_PER_LINE && k<FLOATS_PER_YEAR; j++, k++) {
if (1 != fscanf(fp, " %f", &f[j])) {
fprintf(stderr, "Problems at reading the %dth float\n", k);
f[j] = 0.0F;
}
}
if (1 != fscanf(fp, " %d", &l)) {
fputs("Problems reading lead-out of line\n", stderr);
}
/* Some output to make sure we did it right */
printf("%2d/%d: [ ", l, year);
for (j=0; j<=(k-1)%FLOATS_PER_LINE; j++) {
printf("%4.2f ", f[j]);
}
printf("]\n");
} /* Loop over all lines per year */
} /* Loop over years */

fclose(fp);
free(line); /* Once more: free the allocated memory */

return 0;
}
 
L

learner

Michael said:
Well, some kind of whitespace has to go at the _beginning_ of the line
in the case of fscanf().

if (1 != fscanf(fp, "\n%*d %d", &year)) {

thanks mike for the coding.
Well, is this practice to use \n to sort eat out the leading white
spaces
in an input stream documented somewhere? I mean I did man and googled
quite a bit
to find out about fscanf, but none give these kind of examples. Also,
when I did
eat in a line at a time and then use sscanf, I don't have to do this \n
first. I guess
I'll need some good reference book or something that I can find these
quirks if you may.

Could you explain just a bit about this line:
fprintf(stderr, "Line %d: line malloc fail\n", __LINE__);
__LINE__ is ??

Thanks.
 
M

Michael Mair

learner said:
thanks mike for the coding.
Well, is this practice to use \n to sort eat out the leading white
spaces in an input stream documented somewhere?

If you read the original standard text or a good man page carefully,
you can find it out by yourself. Note that I could have used ' ' or
'\t' as well -- any sort of whitespace suffices.

A good standard library reference:
http://www.dinkumware.com/refxc.html
I mean I did man and googled
quite a bit
to find out about fscanf, but none give these kind of examples. Also,
when I did
eat in a line at a time and then use sscanf, I don't have to do this \n
first.

Yes, this is what I indicated in my first reply.
I guess
I'll need some good reference book or something that I can find these
quirks if you may.

Could you explain just a bit about this line:
fprintf(stderr, "Line %d: line malloc fail\n", __LINE__);
__LINE__ is ??

__LINE__, __FILE__ (in C99 __func__) are predefined identifiers
which can be used to obtain the line, file name (and function name) in
the current source file. Useful for debugging.
Look up these and maybe the #line preprocessing directive in
a good C book.

Must run, thus somewhat short reply.


Cheers
Michael
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,154
Members
46,702
Latest member
LukasConde

Latest Threads

Top