Binary Files Problem

Hi! I am a computer science student and I'm currently working on files, the subject on which I do not have a massive amount of conceptual understanding. I can quickly understand though, if someone could help me out on this problem.

I'm creating a program for a Restaurant that can take in Customer's information and store them in a binary file. There's a structure for the Customer information from which I have created 10 objects in an array called C.

Now all of that runs perfectly (the entering of information) but I'm getting stuck in this particular section of the code that employs the use of files.

I've created a stream class object fio in int main() like this:

fstream fio ("Restaurant.bin",ios::in|ios::out|ios::binary);

and then I've done this to accept each customer's information into the binary file:

cout<< "\nEnter number of reservations you wish to make: \t";
cin>>n;
while(!fio.eof())
{
if(!fio)
{
cout<< "\n \nFile cannot be opened. \n";
return 1;
}

for(i=0;i<n;i++)
{
cout<< "\nEnter details for reservation "<<i+1<< "\n";
C[i].AddCust();
fio.write((char *)& C[i], sizeof(C[i]));
}
fio.seekg(0);
system ("cls");
cout<< "\n \nReservations made for the day: \n \n";
for(i=0;i<n;i++)
{
fio.read((char *)& C[i], sizeof(C[i]));
C[i].DisplayCust();
}
}
fio.close();

No matter what I've tried it always says displays "File cannot be opened". I have only written this code and since I'm a little confused about files I haven't done ANYTHING else (eg. going to Debug file and doing stuff there).

Help would be much appreciated.
Last edited on
No matter what I've tried it always says displays "File cannot be opened".


If the file doesn't exist, it cannot be opened for input, that's why it fails. A simple fix, add ios::trunc to the open mode, it will discard any existing file contents, or create a new file if none exists.

The loop while(!fio.eof()) would usually be inadvisable. In this case it seems to serve no purpose at all.


Just for demonstration purposes, I used two separate arrays here. That isn't necessary, but on the other hand, since you have the original array, there is no need for a file either. So, just as a somewhat useless example, this code writes the array to a file, reads it back into a different array, then displays the contents of that second array.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <iomanip>
#include <fstream>

using namespace std;

struct Reservation {
    int  id;
    char name[30];
    
    void AddCust() { }
    
    void DisplayCust() const
    {
        cout << setw(10) << id << "  " << name << '\n';
    }
    
};


int main()
{
    
    Reservation C[10] = {
        {123, "Fred Bloggs"},
        {456, "Suzy Smythe"},
        {789, "Arthur Clarke"}
    };
    
    fstream fio ("Restaurant.bin", ios::in | ios::out | ios::binary | ios::trunc);
    if (!fio)
    {
        cout << "\n \nFile cannot be opened. \n";
        return 1;
    }

    int n = 3;
    
    for (int i=0; i<n; i++)
    {
        fio.write(reinterpret_cast<char *>(& C[i]), sizeof(C[i]));
    }
    
    
// Now display each customer's information from the binary file:    
    fio.seekg(0);
//    system ("cls");
    
    cout << "\n \nReservations made for the day: \n \n";
    
    Reservation res[10];
    int size = 0;
    
    while (fio.read(reinterpret_cast<char *>(&res[size]), sizeof (Reservation)))
    {
        size++;
    }
    
    for (int i=0; i<size; ++i)
    {
        res[i].DisplayCust();
    }

    fio.close();
}


Note, I also used the C++ style cast - it does look a little more verbose, but it's good to get familiar with the C++ way of doing things.
It's better to use perror or strerror(errno) to get a proper error message.
Also forget about !fio.eof(). There are tons of posts about the problem and why it shouldn't be used.
@Chervil Thank you so much! This certainly cleared my problem. I'll figure out the problems by tonight but a crystal clear example like this one is what I needed. Can you suggest a good website to better develop my concepts?
@neha candy I'm not sure of any particular website, there is a tutorial on this site, but it may be too concise to give the fuller understanding you want.
@Chervil

I have finally succeeded. It's been a while but I was busy with my other school projects. There's only one slight problem left. My string outputs contains a bunch of junk values in the beginning and I have tried every method that's possible for me to remove it and have had no luck. Could you try to find the problem, please? Here's the code snippet.

From the AddCust() function in my structure Reservation:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void AddCust()
        {
            cout<< "\n \t \t \t \t \tNew Customer\n \n \n";
            cout<< "Enter name: \t";
            cin.clear();cin.getline(Name, 50);
            cin.getline(Name,50);
            cout<< "\nEnter E-mail ID: \t";
            cin.getline(Email,50);
            cout<< "\nEnter working number: \t";
            cin>>Number;
            cout<< "\nEnter date of arrival: \n";
            cout<< "\tDate: \t";
            cin>>TA.date;
            cout<< "\n \tMonth: \t";
            cin>>TA.month;
            cout<< "\n \tYear: \t";
            cin>>TA.year;
            cout<< "\nEnter time of arrival: \n";
            cin>>TA.time;
        }


From the DisplayCust() function in my structure Reservation:
1
2
3
4
5
6
7
8
9
  void DisplayCust() const
        {
            // cout<< "\n \nCustomer Number: \t"<<cout<<Customer_Code;
            cout<< "\n \nName: \t"<<cout<<Name;
            cout<< "\n \nE-mail ID: \t"<<cout<<Email;
            cout<< "\n \nNumber: \t"<<cout<<Number;
            cout<< "\n \nDate of next Arrival: \t";
            cout<<TA.date<< "/"<<TA.month<< "/"<<TA.year<< " at "<<TA.time<< "hours.";
        }



From the main function:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
                    for (i=0;i<n;i++)
                    {
                        C[i].AddCust();
                    }
                    if(!fio)
                    {
                        cout<< "\n \nFile cannot be opened. \n";
                        return 1;
                    }

                    for(i=0;i<n;i++)
                    {
                        //cout<< "\nEnter details for reservation "<<i+1<< "\n";
                        //C[i].AddCust();
                        //fio.write((char *)& C[i], sizeof(C[i]));
                        fio.write(reinterpret_cast<char *>(& C[i]), sizeof(C[i]));
                    }
                    fio.seekg(0);
                    system ("cls");
                    cout<< "\n \nReservations made for the day: \n \n";

                    Customer cust[10];
                    int size=0;

                    while (fio.read(reinterpret_cast<char *>(&cust[size]), sizeof (Customer)))
                    {
                        size++;
                    }

                    for (int i=0;i<size;++i)
                    {
                        cust[i].DisplayCust();
                    }


And finally here's the output:



Reservations made for the day:



Name:   0x6fefeb24neha

E-mail ID:      0x6fefeb24mehshakjcn

Number:         0x6fefeb2434

Date of next Arrival:   32/32/32 at 32hours.

Name:   0x6fefeb24neha

E-mail ID:      0x6fefeb24eakjcnjac

Number:         0x6fefeb2443

Date of next Arrival:   2/223/2324 at 343hours.

Name:   0x6fefeb24Neha

E-mail ID:      0x6fefeb24nehayay@yipee.com

Number:         0x6fefeb2455602829

Date of next Arrival:   23/11/2017 at 1600hours.

Name:   0x6fefeb24neha

E-mail ID:      0x6fefeb24whcjdka

Number:         0x6fefeb248732632

Date of next Arrival:   32/3/3223 at 2332hours.

Name:   0x6fefeb24neha

E-mail ID:      0x6fefeb24ekjabs

Number:         0x6fefeb2489237

Date of next Arrival:   22/323/3232 at 12hours.

Go back to Start page? (y/n)


Any help would be great. Thanks in advance.
Last edited on
I can see one problem. There is an unwanted <<cout appearing in the middle of several statements in the DisplayCust() function.

Here, original code:
1
2
3
4
5
6
7
8
9
  void DisplayCust() const
        {
            // cout<< "\n \nCustomer Number: \t"<<cout<<Customer_Code;
            cout<< "\n \nName: \t"<<cout<<Name;
            cout<< "\n \nE-mail ID: \t"<<cout<<Email;
            cout<< "\n \nNumber: \t"<<cout<<Number;
            cout<< "\n \nDate of next Arrival: \t";
            cout<<TA.date<< "/"<<TA.month<< "/"<<TA.year<< " at "<<TA.time<< "hours.";
        }



Should be:
1
2
3
4
5
6
7
8
9
  void DisplayCust() const
        {
            // cout<< "\n \nCustomer Number: \t"<<Customer_Code;
            cout<< "\n \nName: \t"<<Name;
            cout<< "\n \nE-mail ID: \t"<<Email;
            cout<< "\n \nNumber: \t"<<Number;
            cout<< "\n \nDate of next Arrival: \t";
            cout<<TA.date<< "/"<<TA.month<< "/"<<TA.year<< " at "<<TA.time<< "hours.";
        }


That should help. There may be other problems, I didn't spend a lot of time looking at the rest.
@Chervil

A huge shout out to you! Thank you so very much, my problems are clear and now I can further work on more functions. Thank you again! :)
Topic archived. No new replies allowed.