#include <stdio.
h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h> // For tolower()
#define MAX_RECORDS 100
#define MAX_STRING_LENGTH 50
#define FILENAME "service_records.txt"
// Structure to represent a service/repair record
typedef struct {
int id;
char customerName[MAX_STRING_LENGTH];
char itemName[MAX_STRING_LENGTH];
char issueDescription[MAX_STRING_LENGTH * 2]; // Longer description
char status[MAX_STRING_LENGTH]; // e.g., "Pending", "In Progress",
"Completed", "Ready for Pickup"
char dateReceived[MAX_STRING_LENGTH]; // Format: YYYY-MM-DD
char dateCompleted[MAX_STRING_LENGTH]; // Format: YYYY-MM-DD (or
"N/A" if not completed)
double estimatedCost;
} ServiceRecord;
// Global array to store service records
ServiceRecord records[MAX_RECORDS];
int recordCount = 0; // Current number of records
// Function prototypes
void displayMenu();
void addRecord();
void viewAllRecords();
void searchRecord();
void updateRecord();
void deleteRecord();
void saveRecordsToFile();
void loadRecordsFromFile();
int getNextId();
void clearInputBuffer();
int isNumeric(const char *str);
int main() {
loadRecordsFromFile(); // Load existing records on startup
int choice;
do {
displayMenu();
printf("Enter your choice: ");
if (scanf("%d", &choice) != 1) {
printf("Invalid input. Please enter a number.\n");
clearInputBuffer();
choice = 0; // Set to an invalid choice to re-display menu
continue;
clearInputBuffer(); // Clear any remaining characters in the buffer
switch (choice) {
case 1:
addRecord();
break;
case 2:
viewAllRecords();
break;
case 3:
searchRecord();
break;
case 4:
updateRecord();
break;
case 5:
deleteRecord();
break;
case 6:
printf("Saving records and exiting. Goodbye!\n");
saveRecordsToFile();
break;
default:
printf("Invalid choice. Please try again.\n");
printf("\n"); // New line for better readability
} while (choice != 6);
return 0;
// Displays the main menu options
void displayMenu() {
printf("--- Service/Repair Database Program ---\n");
printf("1. Add New Record\n");
printf("2. View All Records\n");
printf("3. Search Record\n");
printf("4. Update Record\n");
printf("5. Delete Record\n");
printf("6. Exit\n");
printf("---------------------------------------\n");
// Clears the input buffer to prevent issues with scanf
void clearInputBuffer() {
int c;
while ((c = getchar()) != '\n' && c != EOF);
// Checks if a string contains only digits
int isNumeric(const char *str) {
if (str == NULL || *str == '\0') {
return 0; // Empty or NULL string is not numeric
while (*str) {
if (!isdigit((unsigned char)*str)) {
return 0; // Found a non-digit character
str++;
return 1; // All characters are digits
// Generates the next available ID for a new record
int getNextId() {
int maxId = 0;
for (int i = 0; i < recordCount; i++) {
if (records[i].id > maxId) {
maxId = records[i].id;
return maxId + 1;
// Adds a new service record
void addRecord() {
if (recordCount >= MAX_RECORDS) {
printf("Database is full. Cannot add more records.\n");
return;
ServiceRecord newRecord;
newRecord.id = getNextId();
printf("\n--- Add New Service Record ---\n");
printf("Customer Name: ");
fgets(newRecord.customerName, MAX_STRING_LENGTH, stdin);
newRecord.customerName[strcspn(newRecord.customerName, "\n")] =
0; // Remove newline
printf("Item Name (e.g., Laptop, Phone, TV): ");
fgets(newRecord.itemName, MAX_STRING_LENGTH, stdin);
newRecord.itemName[strcspn(newRecord.itemName, "\n")] = 0;
printf("Issue Description: ");
fgets(newRecord.issueDescription, MAX_STRING_LENGTH * 2, stdin);
newRecord.issueDescription[strcspn(newRecord.issueDescription, "\n")]
= 0;
printf("Status (e.g., Pending, In Progress, Completed): ");
fgets(newRecord.status, MAX_STRING_LENGTH, stdin);
newRecord.status[strcspn(newRecord.status, "\n")] = 0;
printf("Date Received (YYYY-MM-DD): ");
fgets(newRecord.dateReceived, MAX_STRING_LENGTH, stdin);
newRecord.dateReceived[strcspn(newRecord.dateReceived, "\n")] = 0;
printf("Date Completed (YYYY-MM-DD or N/A if not completed): ");
fgets(newRecord.dateCompleted, MAX_STRING_LENGTH, stdin);
newRecord.dateCompleted[strcspn(newRecord.dateCompleted, "\n")] =
0;
char costStr[MAX_STRING_LENGTH];
printf("Estimated Cost (e.g., 1500.50): ");
fgets(costStr, MAX_STRING_LENGTH, stdin);
newRecord.estimatedCost = atof(costStr); // Convert string to double
records[recordCount] = newRecord;
recordCount++;
printf("Record added successfully! ID: %d\n", newRecord.id);
saveRecordsToFile(); // Auto-save after adding
}
// Displays all service records
void viewAllRecords() {
if (recordCount == 0) {
printf("No service records found.\n");
return;
printf("\n--- All Service Records (%d) ---\n", recordCount);
printf("%-5s %-20s %-15s %-30s %-15s %-12s %-12s %-10s\n",
"ID", "Customer Name", "Item Name", "Issue", "Status",
"Date Rcvd", "Date Cmplt", "Cost");
printf("----------------------------------------------------------------------------------------------
-------------------------------\n");
for (int i = 0; i < recordCount; i++) {
// Truncate long descriptions for display
char displayIssue[31];
strncpy(displayIssue, records[i].issueDescription, 30);
displayIssue[30] = '\0';
if (strlen(records[i].issueDescription) > 30) {
strcat(displayIssue, "...");
printf("%-5d %-20s %-15s %-30s %-15s %-12s %-12s %-10.2f\n",
records[i].id,
records[i].customerName,
records[i].itemName,
displayIssue,
records[i].status,
records[i].dateReceived,
records[i].dateCompleted,
records[i].estimatedCost);
printf("----------------------------------------------------------------------------------------------
-------------------------------\n");
// Searches for a record by customer name or item name
void searchRecord() {
if (recordCount == 0) {
printf("No records to search.\n");
return;
char searchTerm[MAX_STRING_LENGTH];
printf("\n--- Search Service Record ---\n");
printf("Enter Customer Name or Item Name to search: ");
fgets(searchTerm, MAX_STRING_LENGTH, stdin);
searchTerm[strcspn(searchTerm, "\n")] = 0;
// Convert search term to lowercase for case-insensitive search
for (int i = 0; searchTerm[i]; i++) {
searchTerm[i] = tolower(searchTerm[i]);
int found = 0;
printf("\nSearch Results:\n");
printf("%-5s %-20s %-15s %-30s %-15s %-12s %-12s %-10s\n",
"ID", "Customer Name", "Item Name", "Issue", "Status",
"Date Rcvd", "Date Cmplt", "Cost");
printf("----------------------------------------------------------------------------------------------
-------------------------------\n");
for (int i = 0; i < recordCount; i++) {
char customerLower[MAX_STRING_LENGTH];
char itemLower[MAX_STRING_LENGTH];
strcpy(customerLower, records[i].customerName);
for (int j = 0; customerLower[j]; j++) {
customerLower[j] = tolower(customerLower[j]);
strcpy(itemLower, records[i].itemName);
for (int j = 0; itemLower[j]; j++) {
itemLower[j] = tolower(itemLower[j]);
if (strstr(customerLower, searchTerm) != NULL || strstr(itemLower,
searchTerm) != NULL) {
char displayIssue[31];
strncpy(displayIssue, records[i].issueDescription, 30);
displayIssue[30] = '\0';
if (strlen(records[i].issueDescription) > 30) {
strcat(displayIssue, "...");
printf("%-5d %-20s %-15s %-30s %-15s %-12s %-12s %-10.2f\n",
records[i].id,
records[i].customerName,
records[i].itemName,
displayIssue,
records[i].status,
records[i].dateReceived,
records[i].dateCompleted,
records[i].estimatedCost);
found = 1;
if (!found) {
printf("No records found matching '%s'.\n", searchTerm);
printf("----------------------------------------------------------------------------------------------
-------------------------------\n");
// Updates an existing service record
void updateRecord() {
if (recordCount == 0) {
printf("No records to update.\n");
return;
int idToUpdate;
char idStr[MAX_STRING_LENGTH]; // Use a string to read ID for
validation
printf("\n--- Update Service Record ---\n");
printf("Enter ID of the record to update: ");
fgets(idStr, MAX_STRING_LENGTH, stdin);
idStr[strcspn(idStr, "\n")] = 0;
if (!isNumeric(idStr)) {
printf("Invalid ID. Please enter a number.\n");
return;
idToUpdate = atoi(idStr);
int foundIndex = -1;
for (int i = 0; i < recordCount; i++) {
if (records[i].id == idToUpdate) {
foundIndex = i;
break;
if (foundIndex != -1) {
printf("Record found (ID: %d).\n", records[foundIndex].id);
printf("Current Customer Name: %s\n",
records[foundIndex].customerName);
printf("Enter new Customer Name (press Enter to keep current): ");
char input[MAX_STRING_LENGTH];
fgets(input, MAX_STRING_LENGTH, stdin);
input[strcspn(input, "\n")] = 0;
if (strlen(input) > 0) {
strcpy(records[foundIndex].customerName, input);
}
printf("Current Item Name: %s\n", records[foundIndex].itemName);
printf("Enter new Item Name (press Enter to keep current): ");
fgets(input, MAX_STRING_LENGTH, stdin);
input[strcspn(input, "\n")] = 0;
if (strlen(input) > 0) {
strcpy(records[foundIndex].itemName, input);
printf("Current Issue Description: %s\n",
records[foundIndex].issueDescription);
printf("Enter new Issue Description (press Enter to keep current): ");
char descInput[MAX_STRING_LENGTH * 2];
fgets(descInput, MAX_STRING_LENGTH * 2, stdin);
descInput[strcspn(descInput, "\n")] = 0;
if (strlen(descInput) > 0) {
strcpy(records[foundIndex].issueDescription, descInput);
printf("Current Status: %s\n", records[foundIndex].status);
printf("Enter new Status (press Enter to keep current): ");
fgets(input, MAX_STRING_LENGTH, stdin);
input[strcspn(input, "\n")] = 0;
if (strlen(input) > 0) {
strcpy(records[foundIndex].status, input);
printf("Current Date Received: %s\n",
records[foundIndex].dateReceived);
printf("Enter new Date Received (YYYY-MM-DD, press Enter to keep
current): ");
fgets(input, MAX_STRING_LENGTH, stdin);
input[strcspn(input, "\n")] = 0;
if (strlen(input) > 0) {
strcpy(records[foundIndex].dateReceived, input);
printf("Current Date Completed: %s\n",
records[foundIndex].dateCompleted);
printf("Enter new Date Completed (YYYY-MM-DD or N/A, press Enter
to keep current): ");
fgets(input, MAX_STRING_LENGTH, stdin);
input[strcspn(input, "\n")] = 0;
if (strlen(input) > 0) {
strcpy(records[foundIndex].dateCompleted, input);
printf("Current Estimated Cost: %.2f\n",
records[foundIndex].estimatedCost);
printf("Enter new Estimated Cost (press Enter to keep current): ");
fgets(input, MAX_STRING_LENGTH, stdin);
input[strcspn(input, "\n")] = 0;
if (strlen(input) > 0) {
records[foundIndex].estimatedCost = atof(input);
printf("Record updated successfully!\n");
saveRecordsToFile(); // Auto-save after updating
} else {
printf("Record with ID %d not found.\n", idToUpdate);
// Deletes a service record
void deleteRecord() {
if (recordCount == 0) {
printf("No records to delete.\n");
return;
int idToDelete;
char idStr[MAX_STRING_LENGTH];
printf("\n--- Delete Service Record ---\n");
printf("Enter ID of the record to delete: ");
fgets(idStr, MAX_STRING_LENGTH, stdin);
idStr[strcspn(idStr, "\n")] = 0;
if (!isNumeric(idStr)) {
printf("Invalid ID. Please enter a number.\n");
return;
idToDelete = atoi(idStr);
int foundIndex = -1;
for (int i = 0; i < recordCount; i++) {
if (records[i].id == idToDelete) {
foundIndex = i;
break;
}
if (foundIndex != -1) {
// Shift elements to the left to overwrite the deleted record
for (int i = foundIndex; i < recordCount - 1; i++) {
records[i] = records[i + 1];
recordCount--;
printf("Record with ID %d deleted successfully!\n", idToDelete);
saveRecordsToFile(); // Auto-save after deleting
} else {
printf("Record with ID %d not found.\n", idToDelete);
// Saves all records to a text file
void saveRecordsToFile() {
FILE *fp = fopen(FILENAME, "w");
if (fp == NULL) {
perror("Error opening file for writing");
return;
for (int i = 0; i < recordCount; i++) {
fprintf(fp, "%d|%s|%s|%s|%s|%s|%s|%.2f\n",
records[i].id,
records[i].customerName,
records[i].itemName,
records[i].issueDescription,
records[i].status,
records[i].dateReceived,
records[i].dateCompleted,
records[i].estimatedCost);
fclose(fp);
printf("Records saved to %s\n", FILENAME);
// Loads records from a text file
void loadRecordsFromFile() {
FILE *fp = fopen(FILENAME, "r");
if (fp == NULL) {
printf("No existing data file found. Starting with empty database.\n");
return;
recordCount = 0; // Reset count before loading
char line[MAX_STRING_LENGTH * 4]; // Buffer for a whole line, larger
than max possible record string
while (fgets(line, sizeof(line), fp) != NULL && recordCount <
MAX_RECORDS) {
// Remove newline character
line[strcspn(line, "\n")] = 0;
ServiceRecord tempRecord;
char *token;
// Parse ID
token = strtok(line, "|");
if (token) tempRecord.id = atoi(token); else continue;
// Parse Customer Name
token = strtok(NULL, "|");
if (token) strncpy(tempRecord.customerName, token,
MAX_STRING_LENGTH - 1);
tempRecord.customerName[MAX_STRING_LENGTH - 1] = '\0';
// Parse Item Name
token = strtok(NULL, "|");
if (token) strncpy(tempRecord.itemName, token,
MAX_STRING_LENGTH - 1);
tempRecord.itemName[MAX_STRING_LENGTH - 1] = '\0';
// Parse Issue Description
token = strtok(NULL, "|");
if (token) strncpy(tempRecord.issueDescription, token,
(MAX_STRING_LENGTH * 2) - 1);
tempRecord.issueDescription[(MAX_STRING_LENGTH * 2) - 1] = '\0';
// Parse Status
token = strtok(NULL, "|");
if (token) strncpy(tempRecord.status, token, MAX_STRING_LENGTH -
1);
tempRecord.status[MAX_STRING_LENGTH - 1] = '\0';
// Parse Date Received
token = strtok(NULL, "|");
if (token) strncpy(tempRecord.dateReceived, token,
MAX_STRING_LENGTH - 1);
tempRecord.dateReceived[MAX_STRING_LENGTH - 1] = '\0';
// Parse Date Completed
token = strtok(NULL, "|");
if (token) strncpy(tempRecord.dateCompleted, token,
MAX_STRING_LENGTH - 1);
tempRecord.dateCompleted[MAX_STRING_LENGTH - 1] = '\0';
// Parse Estimated Cost
token = strtok(NULL, "|");
if (token) tempRecord.estimatedCost = atof(token); else continue;
records[recordCount++] = tempRecord;
fclose(fp);
printf("Loaded %d records from %s\n", recordCount, FILENAME);