1

So I'm writing a code for a program with multiple menus that write different struct datas to a file and then with another menu that displays the data written in those files. Here's the code for the menu:

void displayall()
{
    FILE *fp;
    int choice=0;
    struct depart loc = {0};
    struct arrive loc1 = {0};
    struct travel trav = {0};
    fp=fopen("traveldat.dat","r");

    while (1)
    {
        fread(&loc,sizeof(loc),1,fp);
        fread(&loc1,sizeof(loc1),1,fp);
        fread(&trav,sizeof(trav),1,fp);
        double distance,time;
        distance = sqrt(pow((loc1.x2-loc.x1),2)+pow((loc1.y2-loc.y1),2));
        time = distance/trav.spd;

        if (feof(fp))
        {
            break;
        }
        printf("\tYour departure location is : %s\n",loc.dep);
        printf("\tWith the x-coordinate : %.2f\n",loc.x1);
        printf("\tAnd the y-coordinate : %.2f\n\n",loc.y1);
        printf("\tYour destination location is : %s\n",loc1.dest);
        printf("\tWith the x-coordinate : %.2f\n",loc1.x2);
        printf("\tAnd the y-coordinate : %.2f\n\n",loc1.y2);
        printf("\tThe distance between these two locations is : %.2fkm\n\n",distance);
        printf("\tYour preferred travel method is : %s\n",trav.mthd);
        printf("\tWhich has a top speed of : %.2f km/h\n\n",trav.spd);
        printf("\tYour  expected travel time is : %.2f hours*\n\n",time);
        printf("\t*Estimation,actual  travel times may vary depending on certain conditions\n\n");
        printf("\tThe system will now display the Main Menu\n\n");
    }
    fclose(fp);
}

The problem I'm facing is that if I go to the menu that writes loc1 or trav before the menu that writes loc, the display menu doesn't work, returns to the main menu, and then refuses to open whenver I try to access it. Is it because fread(&loc) is placed before the other freads? Or is there something I'm missing? Apologies in advance if this code is an eyesore or if I'm asking wrongly, I've only been learning programming for about a month.

Edit: loc1 and loc code as requested

void arrival_location_menu()
{
FILE *fp;
int choice=0;
struct arrive loc1;
fp=fopen("traveldat.dat","a");
printf("Please select your option (Destination location)\n");
printf("1.HOME\n");
printf("2.Andromeda Galaxy\n");
printf("3.The Library\n");
printf("4.Cprogramming.com\n");
printf("5.Return to main menu\n");
scanf("%d",&choice);
fflush (stdin);

switch (choice)
{
case 1: loc1.x2 = 3750;
        loc1.y2 = 3450;
        loc1.dest = "HOME";
        system("CLS");
        break;

case 2: loc1.x2 = 9870;
        loc1.y2 = 5660;
        loc1.dest = "Andromeda Galaxy";
        system("CLS");
        break;

case 3: loc1.x2 = 1367;
        loc1.y2 = 3123;
        loc1.dest = "The Library";
        system("CLS");
        break;

case 4: loc1.x2 = 2133;
        loc1.y2 = 4767;
        loc1.dest = "stackoverflow.com";
        system("CLS");
        break;

case 5: system("CLS");
        break;

default: printf("Invalid option! Returning you to main menu...\n");
}
fwrite(&loc1,sizeof(loc1),1,fp);

fclose(fp);
return;
}


//DEPARTURE MENU
void departure_location_menu()
{
FILE *fp;
int choice=0;
struct depart loc;
fp=fopen("traveldat.dat","w");
printf("Please select your option (Departure location)\n");
printf("1.UTAR\n");
printf("2.PLUTO\n");
printf("3.IDK\n");
printf("4.UMM\n");
printf("5.Return to main menu\n");
scanf("%d",&choice);
fflush (stdin);

switch (choice)
{
case 1: loc.x1 = 1738;
        loc.y1 = 1997;
        loc.dep = "UTAR";
        system("CLS");  
        break;

case 2: loc.x1 = 9850;
        loc.y1 = 5675;
        loc.dep = "PLUTO";
        system("CLS");
        break;

case 3: loc.x1 = 1363;
        loc.y1 = 3125;
        loc.dep = "IDK";
        system("CLS");
        break;

case 4: loc.x1 = 2130;
        loc.y1 = 4785;
        loc.dep = "UMM";
        system("CLS");
        break;

case 5:
    system("CLS");
    break;

default: printf("Invalied option!\n");
}
fwrite(&loc,sizeof(loc),1,fp);

fclose(fp);
return;
}
Thomas Baruchel
  • 7,236
  • 2
  • 27
  • 46
Eric Raj
  • 21
  • 4
  • It's not clear from your post , but are you reading from this file while the same file is already open for writing? – M.M Dec 07 '15 at 09:27
  • Well if you write `loc1` before `loc` and you did not specify an offset for `loc1` then it WILL be before `loc`. Can you please show us the code that writes `loc1` and `loc`? – RedX Dec 07 '15 at 09:28
  • Also this is [incorrect use of feof](http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) ; instead you should check that all three `fread` succeeded – M.M Dec 07 '15 at 09:28
  • Why assume that the quickest distance is a straight line? Polar coordinates, Manhattan geometry? – Ed Heal Dec 07 '15 at 09:37
  • @M.M When I follow use the loc menu first followed by the loc1 menu and finally the trav menu it is able to display them all, when I use loc->trav->loc1 the program crashes when trying to display, and basically any other variation I've tried doesnt work. Is that what you were asking me to check? I'm a little unsure – Eric Raj Dec 07 '15 at 09:38
  • @EdHeal Mainly cause I've put the locations as non-existent places so it'd be easier to calculate a distance and time. – Eric Raj Dec 07 '15 at 09:41
  • Surely a location is a place? – Ed Heal Dec 07 '15 at 09:42
  • 1
    Sorry, so you'are asking why it doesn't work to write `loc`, then `trav`, and then `loc1`; but read in `loc`, then `loc1`, then `trav` ?? – M.M Dec 07 '15 at 09:46
  • Well yes but not looking too deep into it, the shortest distance between the Earth and the Moon is a straight line, minus the obvious challenges of travelling this distance like gravity of neighbouring objects and such, this is the route you want to take, cause it would mean less travel time, which is what this program is trying to do, provide the shortest travel time based on your choies, I even noted that this time may be incorrect in the code here : printf("\t*Estimation,actual travel times may vary depending on certain conditions\n\n"); – Eric Raj Dec 07 '15 at 09:49
  • @M.M yeah, am I supposed to be using a different function? does fread read from the file line by line and can't find an item if it isn't written where it thinks it is? – Eric Raj Dec 07 '15 at 09:54
  • No, it reads in order from the file. It doesn't think anything is anywhere, it just reads bytes in order. Calling `fread` with size `500` is equivalent to calling `fgetc` 500 times to get 500 characters. They read in order from the start of the file unless you use a `fseek` command. – M.M Dec 07 '15 at 09:55
  • Your reading code reads the first `sizeof(loc)` bytes from the file, and stores them in `loc`. Then it reads the next `sizeof(loc1)` bytes from the file and stores that in `loc1`. If you had actually written `trav` to the file after `loc` then you have stored part of `trav` in `loc1`. – M.M Dec 07 '15 at 09:57
  • Ah ok,so if it doesn't follow the order it's written in it stores the wrong data to the wrong places. That makes sense. Is there a way to bypass this so it stores `sizeof(loc)` to `loc` alone and not to `loc1` or `trav`? – Eric Raj Dec 07 '15 at 10:02
  • Between the Moon and Earth - You have to take into account where the moon will be at that time, how to capture its gravity. Perhaps get a boost from Earths gravity using a slingshot – Ed Heal Dec 07 '15 at 10:09
  • @EdHeal might not find a way to slingshot fast enough – Eric Raj Dec 07 '15 at 10:51

1 Answers1

0

You seem to be asking if you can read data from anywhere in the file. Yes you can.

There is a function called fseek() to adjust the file pointer. The file pointer is the location next read from or written too.

There is also a function called ftell() to read the current file pointer. That's important if you're going to change the file pointer and want to restore it later.

I would also suggest you get into the habit of initializing variables ( even if it's to NULL or zero ), and of checking return values from functions. These two simple things can make debugging so much simpler.

I believe user @m-m has already explained the coding logic error.