In this project, we’ll create a simple file-based database using file operations in C++. The goal is to implement basic database functionalities such as adding records, reading records, and searching for records from a file. This project will provide practical experience in working with files and help you better understand how to manage data using file-based storage.
A file-based database is a system where data is stored in files rather than in a more complex database system like MySQL or SQLite. In this simple version, we’ll create a database where records (such as user details or product information) are stored in a binary file, and we’ll implement basic CRUD (Create, Read, Update, Delete) operations using file handling.
For this example, let’s assume we are creating a contact management database where each record stores a person’s name, phone number, and email.
Each record will consist of:
We will store each record in a binary file to ensure efficiency and compactness. For simplicity, we will use a fixed-size structure to represent each record.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
// Define a structure for the database record
struct Contact {
char name[100];
char phoneNumber[15];
char email[100];
// Constructor to initialize the contact details
Contact(const string& n = "", const string& p = "", const string& e = "") {
strncpy(name, n.c_str(), sizeof(name) - 1);
strncpy(phoneNumber, p.c_str(), sizeof(phoneNumber) - 1);
strncpy(email, e.c_str(), sizeof(email) - 1);
}
};
We’ll open a binary file using the fstream class. The file will be used for both reading and writing, and we’ll use the binary mode (ios::binary) for efficient data storage.
fstream database("contacts.dat", ios::in | ios::out | ios::binary);
if (!database) {
cout << "Error opening file!" << endl;
return 1;
}
Now let’s implement the basic database operations: add, read, and search.
To add a new contact, we will create a function that accepts contact details and writes them to the file.
void addContact(fstream& database, const Contact& newContact) {
// Move the file pointer to the end of the file
database.seekp(0, ios::end);
// Write the contact record to the file
database.write(reinterpret_cast<const char*>(&newContact), sizeof(Contact));
cout << "Contact added successfully!" << endl;
}
In this function:
seekp(0, ios::end): Moves the write pointer to the end of the file, so new records are added at the end.database.write(): Writes the contact data (in binary format) to the file.We’ll create a function that reads all records in the database and displays them.
void readContacts(fstream& database) {
database.seekg(0, ios::beg); // Move the read pointer to the beginning
Contact tempContact;
cout << "Contacts in the database: " << endl;
while (database.read(reinterpret_cast<char*>(&tempContact), sizeof(Contact))) {
cout << "Name: " << tempContact.name << ", Phone: " << tempContact.phoneNumber
<< ", Email: " << tempContact.email << endl;
}
}
In this function:
seekg(0, ios::beg): Moves the read pointer to the beginning of the file.database.read(): Reads a record from the file into the tempContact structure.To search for a specific record, we’ll implement a function that accepts a name and searches for it in the file.
void searchContact(fstream& database, const string& name) {
database.seekg(0, ios::beg); // Move the read pointer to the beginning
Contact tempContact;
bool found = false;
while (database.read(reinterpret_cast<char*>(&tempContact), sizeof(Contact))) {
if (name == tempContact.name) {
cout << "Contact found!" << endl;
cout << "Name: " << tempContact.name << ", Phone: " << tempContact.phoneNumber
<< ", Email: " << tempContact.email << endl;
found = true;
break;
}
}
if (!found) {
cout << "Contact not found." << endl;
}
}
In this function:
Now, let’s create a simple menu-driven program that lets the user interact with the database to add, read, and search contacts.
int main() {
fstream database("contacts.dat", ios::in | ios::out | ios::binary | ios::app);
if (!database) {
cout << "Error opening file!" << endl;
return 1;
}
int choice;
string name, phone, email;
while (true) {
cout << "1. Add Contact" << endl;
cout << "2. View All Contacts" << endl;
cout << "3. Search Contact" << endl;
cout << "4. Exit" << endl;
cout << "Enter your choice: ";
cin >> choice;
switch (choice) {
case 1:
// Add a new contact
cout << "Enter name: ";
cin.ignore();
getline(cin, name);
cout << "Enter phone number: ";
getline(cin, phone);
cout << "Enter email: ";
getline(cin, email);
addContact(database, Contact(name, phone, email));
break;
case 2:
// View all contacts
readContacts(database);
break;
case 3:
// Search for a contact by name
cout << "Enter name to search: ";
cin.ignore();
getline(cin, name);
searchContact(database, name);
break;
case 4:
// Exit the program
database.close();
return 0;
default:
cout << "Invalid choice. Please try again." << endl;
}
}
}
After implementing the database, test it by:
Once the basic file-based database is working, you can enhance it by adding features such as:
Building a file-based database in C++ gives you hands-on experience with file operations, structures, and the basics of data management. This project demonstrates how to: