Thread: Read specific values from a file store them in arrays

  1. #1
    Registered User
    Join Date
    Mar 2013
    Posts
    20

    Read specific values from a file store them in arrays

    Hello guys..!

    What i try to do is to write a code which reads some specific values from a file and stores them in an array. My File looks like this

    Code:
     XFOIL         Version 6.96  
     Calculated polar for: Myfoil                                          
      
     1 1 Reynolds number fixed          Mach number fixed         
      
     xtrf =   1.000 (top)        1.000 (bottom)  
     Mach =   0.000     Re =     0.200 e 6     Ncrit =   4.000
      
       alpha    CL        CD       CDp       CM     Top_Xtr  Bot_Xtr
      ------ -------- --------- --------- -------- -------- --------
      -5.000  -0.3878   0.06508   0.06153  -0.0244   1.0000   0.0121
      -4.000  -0.2482   0.05038   0.04638  -0.0478   0.9968   0.0186
      -3.000  -0.1148   0.03410   0.02946  -0.0643   0.9903   0.0224
      -2.000   0.0165   0.02408   0.01845  -0.0718   0.9834   0.0379
      -1.000   0.1420   0.01608   0.00891  -0.0717   0.9759   0.0098
       0.000   0.2613   0.01247   0.00479  -0.0724   0.9650   0.0092
       1.000   0.4559   0.01317   0.00250  -0.0897   0.0119   0.2606
       2.000   0.5898   0.01434   0.00545  -0.0948   0.0102   1.0000
       3.000   0.6859   0.01915   0.01044  -0.0906   0.0063   1.0000
       4.000   0.7850   0.02724   0.01952  -0.0854   0.0063   1.0000
      -5.000  -0.1247   0.00000  -0.00040  -0.0964   0.0000   0.0000
      -4.000  -0.0067   0.00000  -0.00036  -0.0970   0.0000   0.0000
      -3.000   0.1112   0.00000  -0.00033  -0.0975   0.0000   0.0000
      -2.000   0.2291   0.00000  -0.00031  -0.0982   0.0000   0.0000
      -1.000   0.3470   0.00000  -0.00028  -0.0988   0.0000   0.0000
       0.000   0.4647   0.00000  -0.00027  -0.0995   0.0000   0.0000
       1.000   0.5823   0.00000  -0.00025  -0.1002   0.0000   0.0000
       2.000   0.6997   0.00000  -0.00024  -0.1010   0.0000   0.0000
       3.000   0.8169   0.00000  -0.00024  -0.1017   0.0000   0.0000
       4.000   0.9339   0.00000  -0.00024  -0.1025   0.0000   0.0000
       5.000   1.0506   0.00000  -0.00024  -0.1034   0.0000   0.0000
       6.000   1.1669   0.00000  -0.00025  -0.1042   0.0000   0.0000
       7.000   1.2829   0.00000  -0.00027  -0.1051   0.0000   0.0000
       8.000   1.3985   0.00000  -0.00029  -0.1060   0.0000   0.0000
       9.000   1.5136   0.00000  -0.00031  -0.1069   0.0000   0.0000
    What i want to do is read the values below the columns apha cl cd and store them into the arrays alpha[],cl[],cd[]. What i have achieved so far is to do this for a variable but not for an array. Also the code below just reads the first line and doesn't go any further. Can you please help me to modify the code...?

    Code:
    double FileRead() {
    
    
    
       double n,cl,cd,result;
       char target[10]={"---"};
       char buff[2000]={""};
       char *ps;
    
    
    
    
       FILE *fp=fopen("save.txt", "r");
    
    
       if(!fp) {
    
    
                printf("Error opening file!\n");
    
    
          return 0;
       }
    
    
       while((fgets(buff, sizeof(buff), fp))!=NULL) {
    
    
    
    
          ps=strstr(buff,target);
    
    
          if(ps) {
    
    
             fgets(buff,sizeof(buff),fp);
             sscanf(buff, "%lf %lf %lf",&n,&cl,&cd);
             printf("cl: %f  cd: %f\n",cl,cd);
             break;
    
    
          }
    
    
       }
    
    
    
    
         result = cl/cd;
         if(result > 300)
    
    
         {
    
    
             result = 0.0;
    
    
             printf("Could not get result\n");
    
    
        }
    
    
    
    
    
    
    
    
    
    
         printf("The result is %1.2f\n",result);
    
    
        fclose(fp);
    
    
       return result;
    
    
    
    
    
    
        return 0;
    }
    Thank you..!

  2. #2
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    You've been at this for a while with little progress.

    You might start with declaring your variables to be arrays and considering this line:

    Code:
    ps=strstr(buff,target);
    This is run every time you read a line from the file. When will this be true? When will be this be false, and how does this play into the function of your read loop?

  3. #3
    Registered User
    Join Date
    Mar 2013
    Posts
    20
    I tried to do something like you've said but i am getting very strange numbers this is what i came up with

    Code:
    double FileRead() {
    
    
    
       double n[25],cl[25],cd[25];
       char target[10]={"---"};
       char buff[2000]={""};
       char *ps;
       int i;
    
    
    
    
       FILE *fp=fopen("save.txt", "r");
    
    
       if(!fp) {
    
    
                printf("Error opening file!\n");
    
    
          return 0;
       }
    
    
       i=0;
    
    
       while((fgets(buff, sizeof(buff), fp))!=NULL && i<25) {
    
    
    
    
          ps=strstr(buff,target);
    
    
          if(ps) {
    
    
             fgets(buff,sizeof(buff),fp);
             sscanf(buff, "%lf %lf %lf",&n[i],&cl[i],&cd[i]);
    
    
             i++;
             break;
    
    
          }
    
    
       }
    for(i = 0;i < 25; i++)
      {
          printf("%f     %f    %f\n",n[i],cl[i],cd[i]);
      }
    
    
    
    
    
    
        return 0;
    }
    But unfortunately i am getting zeros and some really long numbers which are not correct..!

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > if(ps)
    The problem is, after you find your magic marker, you only read ONE more line and that's it.

    You need two while loops

    Code:
    // find the marker
    while ( fgets( ) ) {
      // found it? then break out
    }
    
    // read the data
    while ( fgets( ) ) {
      // too much data, then break out
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Mar 2013
    Posts
    20
    OK i finally found how to do it...!!! This is the code i use does anyone has any better suggestion...??

    Code:
    #include <stdio.h>#include <stdlib.h>
    #include <string.h>
    #include <math.h>
    
    
    #define ALPHA_SEGMENTS 14
    
    
    double FileRead()
    {
        double n[ALPHA_SEGMENTS],cl[ALPHA_SEGMENTS],cd[ALPHA_SEGMENTS],clpower[ALPHA_SEGMENTS],clpowersum,cdsum,result;
        FILE *fd;
        char filename[] = "save.txt";
        char buff[1024];
        int i;
    
    
        clpowersum =0;
        cdsum =0;
        result =0;
    
    
        for(i=0;i<ALPHA_SEGMENTS;i++)
        {
            n[i] = 0;
            cl[i] = 0;
            cd[i] = 0;
            clpower[i] =0;
    
    
        }
    
    
        if ((fd = fopen(filename, "r")) != NULL)
        {
            fseek(fd, 431, SEEK_SET);
            while(!feof(fd))
            {
                memset(buff, 0x00, 1024);
    
    
    
    
                for(i=0;i<ALPHA_SEGMENTS;i++)
                {
                    fscanf(fd, "%[^\n]\n", buff);
                    sscanf(buff, "%lf %lf %lf",&n[i],&cl[i],&cd[i]);
                    printf("n[%d]=%1.5f    cl[%d]=%f    cd[%d]=%f\n",i,n[i],i,cl[i],i,cd[i]);
                    /*printf("alpha:%1.5f cl: %1.5f  cd: %1.5f\n",n,cl,cd);*/
    
    
                    if(cl[i] < 0)
                    {
                        cl[i] = 0;
                    }
    
    
                    clpower[i] = pow(cl[i],1.5);
                    clpowersum = clpowersum + clpower[i];
                    cdsum = cdsum + cd[i];
    
    
                }
    
    
            }
    
    
        }
        for(i=0;i<ALPHA_SEGMENTS;i++)
            printf("clpower[%d] = %f\n",i,clpower[i]);
    
    
        printf("The sum of clpower is %f the cdsum = %f\n",clpowersum,cdsum);
    
    
        result = (clpowersum/cdsum);
    
    
        printf("The result is %f\n",result);
        return result;
    
    
    }

  6. #6
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Quote Originally Posted by Ghost_ View Post
    does anyone has any better suggestion...??
    Yes. Do as Salem said. I don't like he use of magic numbers, and your file header doesn't look like it would be the same size every time such a file is generated.
    Kurt

  7. #7
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Code:
        if ((fd = fopen(filename, "r")) != NULL)
        {
            fseek(fd, 431, SEEK_SET);
            while(!feof(fd))
            {
    Read: FAQ > Explanations of... > Why it's bad to use feof() to control a loop
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  8. #8
    Registered User
    Join Date
    Mar 2013
    Posts
    20
    Guys you were right the file isn't a fixed size but it has a standard form. So the fseek method to put the pointer at a specific place and then read from this point and below doesn't work very well..!

    So i thought an another method to discard all lines till line 10 and then read from that line and below till the end of file..! I came up with the code below but it has a problem. It doesn't read all the lines but for example it reads line 11 then line 13 then 15 etc it jumps one line..?

    Can you please help me to fix this..?

    Code:
    double FileRead(){
        double n[ALPHA_SEGMENTS],cl[ALPHA_SEGMENTS],cd[ALPHA_SEGMENTS],clpower[ALPHA_SEGMENTS],clpowersum,cdsum,result;
        FILE *fd;
        char filename[] = "save.txt";
        char buff[1024];
        int i,cur_line;
    
    
    
    
        clpowersum =0;
        cdsum =0;
        result =0;
    
    
        for(i=0;i<ALPHA_SEGMENTS;i++)
        {
            n[i] = 0;
            cl[i] = 0;
            cd[i] = 0;
            clpower[i] =0;
    
    
        }
        i=0;
        cur_line = 0;
    
    
    
    
        if ((fd = fopen(filename, "r")) != NULL)
        {
            fseek(fd, 0, SEEK_SET);
            while(fgets(buff,sizeof(buff),fd) != NULL)
            {
               /* memset(buff, 0x00, 1024);*/
    
    
                    if(cur_line > 10)
                    {
                    fgets(buff,sizeof(buff),fd);
                    sscanf(buff, "%lf %lf %lf",&n[i],&cl[i],&cd[i]);
                    printf("n[%d]=%1.5f    cl[%d]=%f    cd[%d]=%f\n",i,n[i],i,cl[i],i,cd[i]);
      i++;
                    }
    
    
    
    
                    if(cl[i] < 0)
                    {
                        cl[i] = 0;
                    }
    
    
                    clpower[i] = pow(cl[i],1.5);
                    clpowersum = clpowersum + clpower[i];
                    cdsum = cdsum + cd[i];
                    cur_line++;
    
    
                }
    
    
            }
    
    
    
    
        for(i=0;i<ALPHA_SEGMENTS;i++)
            printf("clpower[%d] = %f\n",i,clpower[i]);
    
    
        printf("The sum of clpower is %f the cdsum = %f\n",clpowersum,cdsum);
    
    
        result = (clpowersum/cdsum);
    
    
        printf("The result is %f\n",result);
    
     if (result > 10000)
            result = 0;
    
    
        return result;
    
    
    }
    Thank you..!

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Look at my example again.

    You've still got fgets() inside fgets()
    Which means you're sometimes reading two lines at a time.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  10. #10
    Registered User
    Join Date
    Mar 2013
    Posts
    20
    OK i changed the above while expression with this one

    Code:
     if ((fd = fopen(filename, "r")) != NULL)    {
            fseek(fd, 0, SEEK_SET);
            while(fgets(buff,sizeof(buff),fd) != NULL)
            {
               /* memset(buff, 0x00, 1024);*/
    
    
                    if(cur_line > 11)
                    {
    
    
                    sscanf(buff, "%lf %lf %lf\n",&n[i],&cl[i],&cd[i]);
                    printf("n[%d]=%1.5f    cl[%d]=%f    cd[%d]=%f\n",i,n[i],i,cl[i],i,cd[i]);
                    /*printf("alpha:%1.5f cl: %1.5f  cd: %1.5f\n",n,cl,cd);*/
                     if(cl[i] < 0)
                    {
                        cl[i] = 0;
                    }
                    i++;
                    }
                    cur_line++;
    
    
                }
    
    
            }
    but now i get a message from windows saying that a problem occured with this program and it will stop working..!!

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    You have no protection against buffer overrun of your arrays.

    I was thinking of
    Code:
    while(fgets(buff,sizeof(buff),fd) != NULL) {
        if ( strstr(buff,"------") != NULL ) break;
    }
    
    i = 0;
    while ( i < ALPHA_SEGMENTS &&
            fgets(buff,sizeof(buff),fd) != NULL ) {
      if ( sscanf(buff, "%lf %lf %lf",&n[i],&cl[i],&cd[i]) == 3 ) {
        i++;
      } else {
        // some error message...
        break;
      }
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  12. #12
    Registered User
    Join Date
    Mar 2013
    Posts
    20
    Salem thank you for your suggestion...! It really helped me a lot

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 19
    Last Post: 01-04-2013, 11:20 PM
  2. Replies: 13
    Last Post: 11-27-2011, 04:45 PM
  3. Replies: 21
    Last Post: 08-07-2011, 09:55 PM
  4. Read values from txt file and store them in structure
    By bojomojo in forum C Programming
    Replies: 6
    Last Post: 12-19-2010, 10:36 AM
  5. Replies: 1
    Last Post: 11-02-2010, 11:18 PM