Thread: array of inputs gets overwritten (binary file reading)

  1. #1
    Registered User
    Join Date
    Sep 2017
    Posts
    41

    array of inputs gets overwritten (binary file reading)

    this program read from file then asks the user if he wants to choose saved inputs or enter new ones , then after file is closed it will open the binary file created by it and ask the user if he wishes to pick one of the values previously entered or enter new ones

    The problem is :
    If the user chooses to enter new values the program will overwrite the old values in data2[0] , so if the user picks the 1st set of values it's actually going to be the 2nd set of values because the the 1st got overwritten.

    Also , I keep getting an error that function " access" is implicit , what does that mean ?


    PLEASE IGNORE EVERYTHING UNDER MAIN , I JUST POSTED SO YOU CAN SEE THE WHOLE CODE , IT'S UNRELATED TOT HE PROBLEM

    Code:
    #include <stdio.h>
    #include <math.h>
    #include <gng1106plplot.h>
    #include <float.h>
    #include <ctype.h>
    
    
    #define NUM_POINTS 1000 // number of points
    #define X_IX 0           // Row index for storing x values
    #define FX_IX 1
    #define TRUE 1
    #define FALSE 0
    #define EPSILON 1e-10
    #define BINFILE "file.bin"
    #define pi 3.1415926535897932384626433832795
    
    
    typedef struct
    {
    
    
       double l; // starting time
       double c; // ending time
       double v; // velocity
       double td; // time
       double pc; // altitude
    
    
    } INFO;
    
    
    // Function Prototypes
    void findRoot(INFO[], int , double * );
    void plotFunc(INFO [], int,double *);
    double func(INFO [],int , double);
    double pfunc(double , int , double , INFO [] );
    void plot(int numPoints, double points[][numPoints]);
    double getMin(double *, int );
    double getMax(double *, int );
    
    
    
    
    int main()
    {
        int i=0;
        int flag = FALSE;
        int flag2;
        int ans;
        INFO data2[5];
        FILE *fp2;
        double root , R;
        double check , check2;
        double f;
        char ans2;
    
    
         if (access( BINFILE, 0 ) != -1 )
         {
             fp2 = fopen(BINFILE, "ab+");
             printf("Do you want to choose previously inputted values? (y/n)\n");
             fflush(stdin);
             scanf("%c",&ans2);
    
    
             if (ans2 == 'y')
                flag = TRUE;
         }
        else fp2 = fopen(BINFILE, "ab+");
    
    
    
    
        while(i < 5 && flag==FALSE)
        {
    
    
          do
          {
              flag2 = TRUE;
            printf("Please enter the value for L:\n");
                scanf("%lf",&data2[i].l);
            printf("Please enter the value for C:\n");
                scanf("%lf",&data2[i].c);
            printf("Please enter the value for the battery voltage:\n");
                scanf("%lf",&data2[i].v);
            printf("Please enter the value for the dissipation time td:\n ");
                scanf("%lf",&data2[i].td);
            printf("Please enter the value for the percentage of the\n"
                    "original charge pc to reach within td\n");
                    scanf("%lf",&data2[i].pc);
    
    
            R = (-2* data2[i].l * log(data2[i].pc))/data2[i].td;
            check = 1/(data2[i].l*data2[i].c);
            check = check - pow((R/(2*data2[i].l)),2) ;
            check2 = sqrt(check);
            f = check2/(2*pi);
    
    
            if(check < 0)
            {
               flag2 = FALSE;
               printf("Invalid input , Please enter a bigger value for td\n");
            }
            if(50/f < data2[i].td)
            {
                flag2 = FALSE;
                printf("Frequency too high; plot may be distorted\n");
            }
    
    
    
    
          }while(flag2 == FALSE);
    
    
    
    
            fwrite(&data2[i].l, sizeof(double), 1, fp2);
            fwrite(&data2[i].c, sizeof(double), 1, fp2);
            fwrite(&data2[i].v, sizeof(double), 1, fp2);
            fwrite(&data2[i].td, sizeof(double), 1, fp2);
            fwrite(&data2[i].pc, sizeof(double), 1, fp2);
    
    
            //fwrite(&data2, sizeof(data2), 1 ,fp2);
            i++;
    
    
            printf("do you want to \n"
            "1. enter a new set of values(max 5)\n"
            "or\n"
            "2.choose a saved set of values\n");
                scanf("%d",&ans);
    
    
            if (ans == 2)
                flag = TRUE;
        }
    
    
        printf("which set of values do you want to use?\n");
            scanf("%d",&ans);
    
    
        rewind(fp2);
    
    
        // compensate for zero element.
        if ( ans-1 > 5)
        {
            printf("out of bounds\n");
            return -1;
        }
        else
        {
            fread(data2, sizeof(data2), ans, fp2);
    
    
        }
    
    
    
    
    
    
    
    
    
    
    findRoot(data2,ans,&root);
    printf("The value of the Resistor is %lf Ohms\n",root);
    
    
    plotFunc(data2,ans,&root);
    
    
    fclose(fp2);
    return 0;
    
    
    }
    
    
    void findRoot(INFO data2[] , int sel , double *root)
    {
    sel = sel -1;
        double upper = sqrt(4*data2[sel].l/data2[sel].c) ;
        double lower = 0;
        double x0 , x1 ;
    
    
        x0=upper;
        x1= lower;
    
    
    
    
    if(func(data2,sel,x0)* func(data2,sel,x1) < 0)
    {
        do
      {
    
    
        *root = (x0+x1)/2;
    
    
        if(func(data2,sel,*root)*func(data2,sel,x1) < 0 )
         x0 = *root;
        else x1 = *root;
    
    
    
    
    
    
    }while(fabs(func(data2,sel,*root)*func(data2,sel,x1)) >  EPSILON);
    
    
    }
    
    
    
    
    
    
    
    
    }
    
    
    double func(INFO data[] ,int sel , double x)
    {
       double root;
    
    
    
    
    
    
       root = exp(-(x*data[sel].td)/(2*data[sel].l));
       root = root - data[sel].pc ;
    
    
    
    
    
    
     return(root);
    
    
    
    
    }
    
    
    void plotFunc(INFO data2[], int sel, double *root)
    {
        int ix;
        double inc;
        double points[2][NUM_POINTS];
        double x;
    
    
        inc = data2[sel-1].td/1000;
        for(ix = 0 ; ix < NUM_POINTS ; ix = ix+1)
        {
    
    
        points[X_IX][ix] = x;           // Save x value
           points[FX_IX][ix] = pfunc(x,sel-1,*root,data2);  // Calculate and save f(x) value
           x = x + inc;                   // update x value for next iteration
        }
        plot(NUM_POINTS, points);
    
    
    }
    
    
    double pfunc(double x,int index,double root ,INFO array2[] )
    {
        double fx;
    
    
        fx = (array2[index].v*array2[index].c)*exp((-root*x)/(2*array2[index].l))*cos(sqrt((1/(array2[index].l*array2[index].c))-pow((root/(2*array2[index].l)),2))*x);
        return(fx);
    
    
    
    
     return(fx);
    
    
    
    
    }
    
    
    void plot(int numPoints ,double points[][numPoints] )
    {
        // Variable declaration
        double minFx, maxFx;  // Minimum and maximum values of f(x)
        // Setup plot configuration
        plsdev("wingcc");  // Sets device to wingcc - CodeBlocks compiler
        // Initialize the plot
        plinit();
        // Configure the axis and labels
        plwidth(3);          // select the width of the pen
        minFx = getMin(points[FX_IX], numPoints);
        maxFx = getMax(points[FX_IX], numPoints);
        plenv(points[X_IX][0],points[X_IX][numPoints-1],
    	      minFx, maxFx, 0, 0);
        plcol0(GREEN);           // Select color for labels
        pllab("x", "f(x)", "Plot of f(x) versus x");
            // Plot the function.
        plcol0(BLUE);    // Color for plotting curve
        plline(numPoints, points[X_IX], points[FX_IX]);
        plend();
    }
    
    
    double getMin(double *array, int n)
    {
        int ix;
        double min = array[0];
         min = DBL_MAX;
        for(ix = 1; ix < n; ix = ix +1)
            if(min > array[ix]) min = array[ix];
        return(min);
    }
    
    
    double getMax(double *array, int n)
    {
        int ix;
        double max = array[0];
        max = -DBL_MAX;
        for(ix = 1; ix < n; ix = ix +1)
            if(max < array[ix]) max = array[ix];
        return(max);
    }

  2. #2
    Registered User
    Join Date
    May 2009
    Posts
    3,773
    I suggest removing the rewind and using an fseek before the fread.

    You need to stop doing things that are not valid like trying to put multiple values into a address that can only hold one.

    Edit: Add code that is not valid most of the time.
    Code:
    fread(data2, sizeof(data2), ans, fp2);
    The above statement is only valid when ans is one; any other value and the statement is no longer valid.

    int fseek(FILE *stream, long offset, int whence);
    fread(3): binary stream input/output - Linux man page

    Tim S.
    Last edited by stahta01; 12-02-2017 at 09:29 AM.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  3. #3
    Banned
    Join Date
    Aug 2017
    Posts
    861
    Code:
       if (access( BINFILE, 0 ) != -1 )
    Code:
    Kamal_Joub_binary_read_write.c:58:10: warning: implicit declaration of function 'access' [-Wimplicit-function-declaration]
    their is nothing to tell the compiler what 'access' is so it can use it. That is the only mention of the word 'access' within your program. If you had a function called access then removed it, well that'd be why you're getting that error now.

  4. #4
    Registered User
    Join Date
    May 2009
    Posts
    3,773
    Quote Originally Posted by userxbw View Post
    Code:
       if (access( BINFILE, 0 ) != -1 )
    Code:
    Kamal_Joub_binary_read_write.c:58:10: warning: implicit declaration of function 'access' [-Wimplicit-function-declaration]
    their is nothing to tell the compiler what 'access' is so it can use it. That is the only mention of the word 'access' within your program. If you had a function called access then removed it, well that'd be why you're getting that error now.
    On Linux, you should include "unistd.h" so access can be declared right.

    access(2) - Linux man page

    Thanks to userxbw for posting the error because I missed that issue in the OP post.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  5. #5
    Banned
    Join Date
    Aug 2017
    Posts
    861
    Quote Originally Posted by stahta01 View Post
    On Linux, you should include "unistd.h" so access can be declared right.

    access(2) - Linux man page

    Thanks to userxbw for posting the error because I missed that issue in the OP post.

    Tim S.
    crazy man crazy, he does not have to. thanks going to right now then see what I see. but maybe that is why he too is getting that error because it is not included in his file.

    edit: that did it, good thing you happened along. now he just needs to read this post and figure out he is missing that header file.
    Last edited by userxbw; 12-02-2017 at 11:57 AM.

  6. #6
    Banned
    Join Date
    Aug 2017
    Posts
    861
    Quote Originally Posted by Kamal Joub View Post
    this program read from file then asks the user if he wants to choose saved inputs or enter new ones , then after file is closed it will open the binary file created by it and ask the user if he wishes to pick one of the values previously entered or enter new ones

    The problem is :
    If the user chooses to enter new values the program will overwrite the old values in data2[0] , so if the user picks the 1st set of values it's actually going to be the 2nd set of values because the the 1st got overwritten.
    the logical thought process for this problem is what?

    you have a file, it has either been or not been written to.

    if new file, create new file, get input write to new file. add it to the file.

    if not new file.
    does user want to add to it, or read from it?

    if add to, what steps need to be taken to ensure that nothing gets over written?

    if reading from file what steps need to be taken to ensure you, the program knows it is a new file or not so it can act accordingly?
    ( because your first question is, " printf("Do you want to choose previously inputted values? (y/n)\n");",
    what if it is a first run. How can there be any data in a file? )

    if user says he wants to read from the file and has never been written to, then what steps need to be taken to know that then report to user the results of these findings?

    if file has been created and data has been entered into the file, then what steps need to be taken to get the proper data to the user?

    that maybe needing a few more thoughts to make it complete.
    Last edited by userxbw; 12-02-2017 at 12:30 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Array Value being Overwritten
    By Jinzo in forum C++ Programming
    Replies: 1
    Last Post: 05-25-2017, 04:54 PM
  2. Replies: 28
    Last Post: 12-01-2013, 12:05 PM
  3. Existing field in struct to be overwritten. BINARY FILES.
    By wacky_jay in forum C Programming
    Replies: 4
    Last Post: 10-08-2012, 11:24 AM
  4. Replies: 7
    Last Post: 11-24-2010, 04:21 AM
  5. Array Elements Overwritten
    By Zoetermeer in forum C Programming
    Replies: 13
    Last Post: 10-09-2008, 06:10 PM

Tags for this Thread