fscanf problem

Discussion in 'C Programming' started by learner, Jun 27, 2005.

  1. learner

    learner Guest

    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.
     
    learner, Jun 27, 2005
    #1
    1. Advertising

  2. learner

    Michael Mair Guest

    learner wrote:
    > 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
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
     
    Michael Mair, Jun 28, 2005
    #2
    1. Advertising

  3. learner

    learner Guest

    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;
    }
     
    learner, Jun 28, 2005
    #3
  4. learner

    Michael Mair Guest

    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.

    learner wrote:
    > 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;
    }

    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
     
    Michael Mair, Jun 28, 2005
    #4
  5. learner

    learner Guest

    Michael Mair wrote:
    >
    > 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.
     
    learner, Jun 29, 2005
    #5
  6. learner

    Michael Mair Guest

    learner wrote:
    > Michael Mair wrote:
    >
    >>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?


    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
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
     
    Michael Mair, Jun 29, 2005
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Thomas Sourmail

    fscanf problem

    Thomas Sourmail, Jun 16, 2004, in forum: C Programming
    Replies:
    7
    Views:
    3,916
    Chris Torek
    Jun 17, 2004
  2. Kay

    fscanf and linked list problem

    Kay, Aug 29, 2004, in forum: C Programming
    Replies:
    7
    Views:
    1,938
  3. fscanf problem

    , Aug 28, 2005, in forum: C Programming
    Replies:
    2
    Views:
    473
    Walter Roberson
    Aug 28, 2005
  4. rsk

    Problem in using fscanf

    rsk, Jul 30, 2007, in forum: C Programming
    Replies:
    10
    Views:
    647
    Peter 'Shaggy' Haywood
    Aug 3, 2007
  5. Problem with fscanf()....

    , Aug 31, 2007, in forum: C Programming
    Replies:
    11
    Views:
    683
    Keith Thompson
    Sep 1, 2007
Loading...

Share This Page