How delete a record from a file - c++

I am working on a code that creates a binary file that holds structures of student data. One of the things i need to do is to delete a record from a file but I don't know how to do that. I'm not sure how I would go about identifying a record based on the ID number and then delete that file. I would appreciate any help, advice or instructions on what to do.
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <string>
#include <iomanip>
#include <stdio.h>
#include <string.h>
using namespace std;
const int NAME_SIZE = 5;
struct Student{
char fname[NAME_SIZE];
char id;
};
int main() {
int choice;
fstream file;
int number;
Student person;
cout << "Choose an option on what to do."<< endl;
cout << "Option 1: Create a Binary File." << endl;
cout << "Option 2: Check if a file exist." << endl;
cout << "Option 3: Populate the records of the file." << endl;
cout << "Option 4: Display contents of the file." << endl;
cout << "Option 5: Append a record to the file." << endl;
cout << "Option 6: Delete a record from the file." << endl;
cout << "Option 7: Search for a record in the file." << endl;
cout << "Option 8: Modify a record from the file." << endl;
cout << "Option 9: Sort the file." << endl;
cout << "Option 10: Wipe a file." << endl;
cin >> choice;
if (choice==1){
char strdata[10000];
file.open("output", ios::binary|ios::app|ios::out);
if(file.is_open())
{
cin.getline(strdata, 10000);
file.seekg(ios_base::end);
file.write(strdata, strlen(strdata));
}
file.close();
cout << "Binary File named output has been created."<< endl;
}
if (choice==2){
file.open("output", ios::in | ios::binary);
if (file.fail()) {
cout << "File could not be opened." << endl;
}
else {
cout << "The file is there" << endl;
}
}
if (choice==3){
file.open("output", ios::out | ios::binary);
file.read(reinterpret_cast<char *>(&person), sizeof(person));
cout << "Populating the record with information."<< endl;
cout << "Enter the following data about a person " << endl;
cout << "First Name: "<< endl;
cin.getline(person.fname, NAME_SIZE);
cout << "ID Number: "<< endl;
cin >> person.id;
file.write(reinterpret_cast<char *>(&person), sizeof(person));
file.close();
}
if (choice==4){
fstream MyFile("output",ios::binary|ios::out);
Student person[3];
for(int i = 0; i < 3; i++)
MyFile.read((char *) &person[i], sizeof(Student));
MyFile.close();
}
if (choice==5){
int i;
char fname;
int id;
fstream file;
file.read(reinterpret_cast<char *>(&person), sizeof(person));
cout << "How many records do you want to append?" << endl;
cin >> number;
file.open("output",ios::out|ios::app|ios::binary);
file.write(reinterpret_cast<char *>(&person), sizeof(person));
for(i=1; i<=number; i++)
{
cout<<"Enter the name: "<< endl;
cin >> fname;
cout<<"Enter ID : "<<endl;
cin >> id;
file<<fname<<endl;
file<<id<<endl;
}
file.close( );
}
if (choice==6){
}
if (choice==7){
}
if (choice==8){
}
if (choice==9){
}
if (choice==10){
char answer;
cout << "Are you sure you want to wipe the file? 1 for Yes or 2 for No" << endl;
cin >> answer;
if (answer==1){
std::ofstream ofs;
ofs.open("output", std::ofstream::out | std::ofstream::trunc|ios::binary);
cout << "Output File has succesfully been deleted"<< endl;
ofs.close();
}
if (answer!=1)
{
cout << "File has not been deleted"<< endl;
}
}
}
```

Related

c++ Problems with pushing structs onto a vector and then saving to an outputfile

I did away with the vector idea, and after a fair bit of faffing around managed to get the struct in and out of a file. I'm really enjoying the challenge of c++, so much to learn!!!
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
struct Account_query
{
public:
char name[50];
char number[50];
};
void AddRecord(Account_query* aq)
{
ofstream fout;
fout.open("Records.out", ios::app | ios::out | ios::binary);
cout << "Enter name: ";
cin >> aq->name;
cout << "Enter account number: ";
cin >> aq->number;
fout.write( reinterpret_cast<const char *>( &(*aq) ), sizeof(Account_query) );
fout.close();
}
void ShowRecord()
{
Account_query aq;
//std::memset(&aq, 0, sizeof(aq));
ifstream inf;
inf.open("Records.out", ios::binary);
if(!inf)
{
cout << "Problem opening"<<endl;
}
cout <<"####Data Out###"<<endl;
while(!inf.eof())
{
inf.read( reinterpret_cast<char *>(&aq.name), sizeof(Account_query::name));
inf.read( reinterpret_cast<char *>(&aq.number), sizeof(Account_query::number));
cout << "Name is: " << aq.name << "Account is: " << aq.number <<endl;
}
}
int main(int argc, const char * argv[]) {
vector<Account_query> list;
cout << "Welcome to Jizz Bank\n";
cout << "Enter one of the following options then press enter\n";
cout << "-----------------------------------\n";
cout << "1) Add Record \n";
cout << "2) Show Records \n";
cout << "3) Search Record \n";
cout << "4) Edit Record \n";
cout << "5) Delete Record \n";
cout << "-----------------------------------\n";
cout << "Enter your choice: ";
int x;
cin >>x;
Account_query a;
Account_query *p = &a;
switch(x)
{
case 1:{
AddRecord(p);//got the data for object now
break;
}
case 2:{
ShowRecord();
break;
}
default:{
exit(0);
}
}
return 0;
}
Previous entry below...
I'm trying to write a console program to learn c++.
In case 1 of the switch I'm dynamically creating a struct and then sending it to a function along with a reference to a vector.
The idea is to input some simple data to populate the struct, then to push this onto a vector and then write this to a file (binary).
The problem seems to be:
fout.write(static_cast<char*> (*it), sizeof(Account_query));
I get, Cannot cast from type 'Account_query' to pointer type 'char *' in Xcode.
I've tried reinterpret_cast amongst other things but that doesn't work either.
Would really appreciate any help,
LD.
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
struct Account_query
{
public:
char name[50];
char number[50];
};
void AddRecord(Account_query* aq, vector<Account_query>& list)
{
ofstream fout;
fout.open("Records.bank", ios::binary | ios::out);
cout << "Enter name: ";
cin >> aq->name;
cout << "Enter account number: ";
cin >> aq->number;
list.push_back(*aq);
for (vector<Account_query>::iterator it=list.begin(); it != list.end(); ++it)
{
fout.write(static_cast<char*> (*it), sizeof(Account_query));
}
fout.close();
}
void ShowRecord()
{
//TODO
}
int main(int argc, const char * argv[]) {
vector<Account_query> list;
cout << "Welcome to Jizz Bank\n";
cout << "Enter one of the following options then press enter\n";
cout << "-----------------------------------\n";
cout << "1) Add Record \n";
cout << "2) Show Records \n";
cout << "3) Search Record \n";
cout << "4) Edit Record \n";
cout << "5) Delete Record \n";
cout << "-----------------------------------\n";
cout << "Enter your choice: ";
int x;
cin >>x;
switch(x)
{
case 1:{
Account_query* a = new Account_query;
AddRecord(a, list);//got the data for object now
break;
}
case 2:{
cout<<"do nowt yet"<<endl;
break;
}
default:{
exit(0);
}
}
return 0;
}
Don't make life difficult for yourself. Start by using std::string, and then just use the operator<< to put the strings in the file (and read from it). e.g.
#include <string>
#include <iostream>
#include <fstream>
struct AccountQuery
{
std::string name;
std::string number;
};
AccountQuery AddRecord()
{
AccountQuery aq;
std::cout << "Enter name: ";
std::cin >> aq.name;
std::cout << "Enter account number: ";
std::cin >> aq.number;
{
std::ofstream fout("Records.out", std::ios::app | std::ios::binary);
fout << aq.name << " " << aq.number << " "; // spaces for simple separation.
}
return aq;
}
void ShowRecord()
{
AccountQuery aq;
std::ifstream fin("Records.out", std::ios::binary);
if(!fin)
{
std::cerr << "Problem opening file.\n";
return;
}
std::cout << "####Data Out###\n";
while(fin >> aq.name && fin >> aq.number) {
std::cout << "Name is: " << aq.name << ", Account is: " << aq.number << '\n';
}
}
int main() {
std::cout
<< "Welcome to Jizz Bank\n"
<< "Enter one of the following options then press enter\n"
<< "-----------------------------------\n"
<< "1) Add Record\n"
<< "2) Show Records\n"
<< "3) Search Record\n"
<< "4) Edit Record\n"
<< "5) Delete Record\n"
<< "6) Exit\n"
<< "-----------------------------------\n";
bool loop = true;
while(loop) {
std::cout << "Enter your choice: ";
int choice;
std::cin >> choice;
switch(choice)
{
case 1: {
AddRecord();//return value unused?
break;
}
case 2: {
ShowRecord();
break;
}
case 6: {
loop = false;
break;
}
default: {
// nothing, could be omitted
break;
}
}
}
}

Reading and writing multiple structs into a file

I'm trying to store multiple structs into an file and my problem is that when I try to add 2 structs into the same file, my second struct overwrites my first struct and when I go print out my first struct, its print out my second struct. I want to have multiple structs in my file that I can display one at a time and edit them one at a time if I want. Any clue on what's wrong with my code?
int main()
{
Record record1;
Record record2;
int choice;
int choice2;
cout << "Welcome to your Records! What do you want to do today?" << endl;
cout << endl << endl;
while(choice2 != -1)
{
cout << " " << endl;
cout << "1) Add new records to the file" << endl;
cout << "2) Display any record in the file" << endl;
cout << "3) Change any record in the file" << endl;
cout << "4) Exit" << endl;
cout << "Your Choice: ";
cin >> choice;
while(choice < 1 || choice > 4)
{
cout << "Invalid choice! Enter again" << endl;
cin >> choice;
}
if(choice == 1)
{
ofstream outFile("RecordFile.dat", ios::out | ios::binary);
AddItem(outFile);
outFile.close();
}
else if(choice == 2)
{
ifstream inFile("RecordFile.dat",ios::out | ios::binary);
DisplayItem(inFile);
inFile.close();
}
else if(choice == 3)
{
ofstream outFile("RecordFile.dat", ios::out | ios::binary);
EditItem(outFile);
outFile.close();
}
else if(choice == 4)
{
choice2 = -1;
}
}
return 0;
}
Header File
struct Record
{
char name[15];
int quantity;
double wholesalecost;
double retailcost;
};
void AddItem(ofstream& outFile);
void DisplayItem(ifstream& inFile);
void EditItem(ofstream& outFile);
Functions
void AddItem(ofstream& outFile)
{
Record record;
cout << "What is the name of this record: ";
cin.ignore();
cin.getline(record.name,15);
cout << "How many do we have(quantity): ";
cin >> record.quantity;
cout << "Whats the whole sale cost: ";
cin >> record.wholesalecost;
cout << "Whats the retail cost of " << record.name << ":";
cin >> record.retailcost;
if(outFile)
{
outFile.write((char*)&(record),sizeof(record));
}
else
{
cout << "File not Found" << endl;
}
}
void DisplayItem(ifstream& inFile)
{
Record record;
int recordnum;
cout << "Enter what record number you want to display " << endl;
cin >> recordnum;
recordnum--;
if(inFile)
{
inFile.seekg(sizeof(Record) * recordnum, ios::beg);
inFile.read(reinterpret_cast<char *>(&record), sizeof(record));
cout << "Name: " << record.name << endl;
cout << "Quantity: " << record.quantity << endl;
cout << "Whole Sale Cost: " << record.wholesalecost << endl;
cout << "Retail Cost: " << record.retailcost << endl;
}
else
{
cout << "File not found" << endl;
}
}
You are writing everything to the beginning of the file, so of course multiple writes overwrite eachother.
You need to define a file format that can contain multiple records and a way to find where to write new records that doesn't overlap with previous ones, as well as an easy way to find the location of existing records.
Have you considered just using a SQL (or other type of) database?

How to put a random number into an array then a text file

So what I am trying to do is put a random number generator from one through ten into an array that has 50 elements and then put that into a text file. My problem is that the code I have written for the code and generator has an error and I can't wrap my head around how to get it into a text file.
#include <iostream>
#include <iomanip>
#include <string>
#include <ctime>
#include<fstream>
using namespace std;
void menu();
string createFile();
void displayNumTotalAverage(string);
void displaySortedNums();
void SearchNum();
void displayLargestNum();
void appendRandomNum(string);
void exit();
void CreateFile();
void printFunc(int[]);
void fillFunc(int[]);
int main()
{
menu();
string FileName;
//createFile();
//makeRandomNum();
system("pause");
return 0;
}
void menu()
{
int choice;
string FileName;
do
{
//program output
cout << "** MENU **" << endl << endl;
cout << "Curret Data File: " << endl << endl;
cout << "(1) Select / create data file (.txt file extention will be added automaticly)" << endl;
cout << "(2) Display all numbers, total and average" << endl;
cout << "(3) Display all numbers sorted" << endl;
cout << "(4) search for a number and display how many times it occurs" << endl;
cout << "(5) display the largest number" << endl;
cout << "(6) Append a random number(s)" << endl;
cout << "(7) Exit the program" << endl << endl;
//user input
cout << "Menu Choice: ";
cin >> choice;
while (choice > 7 || choice < 1)
{
cout << "Menu Choice: ";
cin >> choice;
}
switch (choice)
{
case 1:
cout << "Choice 1";
createFile();
break;
case 2:
cout << "Choice 2";
displayNumTotalAverage(FileName.c_str());
break;
case 3:
cout << "Choice 3";
break;
case 4:
cout << "Choice 4";
break;
case 5:
cout << "Choice 5";
break;
case 6:
cout << "Choice 6";
appendRandomNum(FileName.c_str());
break;
}
} while (choice != 7);
}
string createFile()<----------------------------------------------------(this)
{
cout << "Create File - Option 1" << endl;
string FileName;
ifstream inFile;
cout << "Name of data file: ";
cin >> FileName;
FileName = "C:\\Users\Wizard\Libraries\Documents\Final Project" + FileName;
inFile.open(FileName + ".txt");
if (inFile)
{
cout << FileName;
}
else
cout << "File not found, creating file.";
system("PAUSE");
return FileName;
}
void displayNumTotalAverage(string FileName)
{
ifstream inFile;
cout << "Display Number Total Average - Option 2" << endl << endl << endl;
inFile.open("C:\\Users\Wizard\Libraries\Documents\Final Project" + FileName + ".txt");
int num;
int total;
cout << "Display Number Total Average function" << FileName;
double average;
bool containsNum = false;
inFile.open(FileName + ".txt");
if (inFile)
{
while (inFile >> num)
{
cout << num << endl;
}
inFile.close();
}
else
{
cout << "Error opening file" << FileName << "." << endl;
}
system("PAUSE");
return;
}
void displaySortedNums()
{
cout << "I AM THE displaySortedNums Function - Option 3" << endl;
system("PAUSE");
return;
}
void searchNum()
{
cout << " I am the searchNum function - option 4" << endl;
system("PAUSE");
return;
}
void displayLargestNum()
{
cout << "I am the displayLargestNum Function - option 5" << endl;
system("PAUSE");
return;
}
void appendRandomNum(string FileName)
{
cout << "i am in the appendRandomNum function - option 6" << endl;
int num = 0;
int count = 0;
ofstream outFile;
outFile.open(FileName + ".txt", ios::app);
cout << "How many random numbers: ";
cin >> count;
for (int i = 0; i < count; i++)
outFile << rand() % 10 << endl;
outFile.close();
cout << endl << "Number(s) Added" << endl << endl;
system("PAUSE");
return;
}
void exit()
{
cout << " I am the exit function - option 7" << endl;
system("PAUSE");
return;
}
void CreateFile()<-----------(and this)
{
int random[50]; //Random Numbers
srand((unsigned)time(NULL));
fillFunc(random);
printFunc(random);
return;
}
void fillFunc(int arr[])
{
for (int i = 0; i < 50; i++)
{
arr[i] = 1 + rand() % 10;
}
}
void printFunc(int arr[])
{
ofstream fout("C:\\Users\Wizard\Libraries\Documents\Final Project");
if (fout.is_open()){
for (int i = 0; i < 50; i++)
{
fout << arr[i] << std::endl;
}
}
}
Assuming you have the tmp folder in your project directory, and pretending the path is: C:\Project\tmp\. This file fails to open: ofstream fout("/tmp/nums.txt");
The first slash is an error. It's as if you tried to open C:\Project\\tmp\.
If you are using Windows, it's like if you changed directory to C:\Project in command promt and then used the command cd \tmp which would result in:
The system cannot find the path specified.
Therefore, omit the first slash and let it be: ofstream fout("tmp/nums.txt"); and it will work. (I assume you're including <fstream> and that you're using the namespace std.)
there are several issues in your original code:
1) you didn't create any text file to output. Are you trying to output using ">" ?
2) you are generating 49 numbers only. To get 50, you need start from 0 instead 1. (int i=0; )
3) You don't have any delimiter in your output. How do you expect to use them?
change your printFunc to something like this:
ofstream fout ("/tmp/nums.txt");
if(fout.is_open() ){
for (int i = 0; i < 50; i++)
{
fout << arr[i] << std::endl;
}
Include fstream #include <fstream>
In printFunc change:
ofstream fout("/tmp/nums.txt");
to
ofstream fout("folder/inner_folder/file.txt", ofstream::out);
The second parameter is the mode for the file. ofstream::out means write access (which is always set for ofstream objects).
At the end of the function close the stream like so:
fout.close();
For reference: http://www.cplusplus.com/reference/fstream/ofstream/ofstream/

Item Inventory Add/Edit/View questions

Okay so i have a lot of questions for this. I was having a lot of trouble but am getting there slowly. So far I have it to where the program will read and write to a file, but it tends to repeat itself a lot. Like when reading from the file itll just keep reading the same information over and over. Also it seems to display the same record twice...and i cant test it further since it only lets me write the first record over and over without ever writing the second. Any help would be great. Also for some reason the edit function seems to pull jibberish when choosing the 1 record...so im stumped. Been working on this for hours with no luck
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
void addRecord(fstream &);
void viewRecord(fstream &);
void changeRecord(fstream &);
int menu();
const int DESC_SIZE = 21;
const int DATE_SIZE = 11;
struct inventoryData
{
char desc[DESC_SIZE]; //Desc up to 20 chars
int quantity; //Item quantity
double wholesale; //Item wholsale Cost
double retail; //Item retail Cost
char date[DATE_SIZE]; //Date able to hold info up to xx/xx/xxxx
};
int main()
{
int selection;
int recordNumber;
fstream dataFile("inventory.dat", ios::in | ios::out | ios::binary);
if (dataFile.fail())
{
// The file does not exist, so create it.
dataFile.open("inventory.dat", ios::out);
}
selection = menu();
while (selection != 4)
{
switch (selection)
{
case 1:
{
viewRecord(dataFile);
break;
}
case 2:
{
addRecord(dataFile);
break;
}
case 3:
{
changeRecord(dataFile);
break;
}
default:
{
cout << "Invalid - Please use 1 to 4" << endl;
break;
}
selection = menu();
}
}
dataFile.close();
return 0;
}
void addRecord(fstream &file)
{
fstream dataFile("inventory.dat", ios::in | ios::out | ios::binary);
inventoryData item;
cout << "Please enter the following data about the item" << endl;
cout << "Description: ";
cin.ignore();
cin.getline(item.desc, DESC_SIZE);
cout << "Quantity: ";
cin >> item.quantity;
cout << "Quantity: ";
cin >> item.quantity;
cout << "Wholesale cost: ";
cin >> item.wholesale;
cout << "Retail price: ";
cin >> item.retail;
cout << "Date (Please use MO/DA/YEAR format: ";
cin >> item.date;
dataFile.write(reinterpret_cast<char *>(&item), sizeof(item));
return;
}
void viewRecord(fstream &file)
{
string output;
fstream dataFile("inventory.dat", ios::in | ios::out | ios::binary);
inventoryData item;
fstream items;
char again;
dataFile.read(reinterpret_cast<char *>(&item), sizeof(item));
while (!items.eof())
{
// Display the record.
cout << "Description: " << item.desc << endl;
cout << "Quantity: " << item.quantity << endl;
cout << "Wholesale Cost: " << item.wholesale << endl;
cout << "Retail Cost: " << item.retail << endl;
cout << "Date: " << item.date << endl;
// Wait for the user to press the Enter key.
cout << "\nPress the Enter key to see the next record.\n";
cin.get(again);
// Read the next record from the file.
dataFile.read(reinterpret_cast<char *>(&item), sizeof(item));
}
}
void changeRecord(fstream &file)
{
fstream dataFile("inventory.dat", ios::in | ios::out | ios::binary);
inventoryData item;
int recordNumber;
cout << "Please choose a record number you want to edit" << endl;
cin >> recordNumber;
dataFile.seekg(recordNumber * sizeof(item), ios::beg);
dataFile.read(reinterpret_cast<char *>(&item), sizeof(item));
cout << "Description: " << item.desc << endl;
cout << "Quantity: " << item.quantity << endl;
cout << "Wholesale cost: " << item.wholesale << endl;
cout << "Retail price: " << item.retail << endl;
cout << "Date: " << item.date << endl;
cout << endl;
// Get the new record data.
cout << "Enter the new data:\n";
cout << "Description: ";
cin.ignore();
cin.getline(item.desc, DESC_SIZE);
cout << "Quantity: ";
cin >> item.quantity;
cout << "Quantity: ";
cin >> item.quantity;
cout << "Wholesale cost: ";
cin >> item.wholesale;
cout << "Retail price: ";
cin >> item.retail;
cout << "Date (Please use MO/DA/YEAR format: ";
cin >> item.date;
// Move back to the beginning of this record's position
dataFile.seekp(recordNumber * sizeof(item), ios::beg);
// Write new record over the current record
dataFile.write(reinterpret_cast<char *>(&item), sizeof(item));
}
int menu()
{
int menuSelection;
cout << fixed << showpoint << setprecision(2);
cout << "----------Inventory----------" << endl;
cout << "1 - View inventory" << endl;
cout << "2 - Add an item" << endl;
cout << "3 - Edit an item" << endl;
cout << "4 - End Program" << endl;
cin >> menuSelection;
if (!cin)
{
cout << "Invalid - Please use 1 to 4" << endl;
cin >> menuSelection;
}
if (menuSelection < 1 || menuSelection > 4)
{
cout << "Invalid - Please use 1 to 4" << endl;
cin >> menuSelection;
}
return menuSelection;
}
int menu()
{
int menuSelection = 0;//initialize
cout << fixed << showpoint << setprecision(2);
cout << "----------Inventory----------" << endl;
cout << "1 - View inventory" << endl;
cout << "2 - Add an item" << endl;
cout << "3 - Edit an item" << endl;
cout << "4 - End Program" << endl;
//*** flush cin, this is inside a loop, it can cause problems
cin.clear();
fflush(stdin);
cin >> menuSelection;
return menuSelection;
}
int main()
{
fstream dataFile("inventory.dat", ios::in | ios::out | ios::binary);
if (dataFile.fail())
{
// The file does not exist, so create it.
dataFile.open("inventory.dat", ios::out);
dataFile.close();
}
for (;;)
{
int selection = menu();
if (selection == 4)
break;
switch (selection)
{
case 1:
viewRecord(dataFile);
break;
case 2:
addRecord(dataFile);
break;
case 3:
changeRecord(dataFile);
break;
default:
cout << "Invalid - Please use 1 to 4" << endl;
break;
}
}
return 0;
}
void viewRecord(fstream &notused)
{
fstream dataFile("inventory.dat", ios::in | ios::out | ios::binary);
inventoryData item;
while (dataFile)
{
dataFile.read(reinterpret_cast<char*>(&item), sizeof(item));
// Display the record.
cout << "Description: " << item.desc << endl;
cout << "Quantity: " << item.quantity << endl;
cout << "Wholesale Cost: " << item.wholesale << endl;
cout << "Retail Cost: " << item.retail << endl;
cout << "Date: " << item.date << endl;
cout << endl;
}
}
void addRecord(fstream &notused)
{
fstream file("inventory.dat", ios::in | ios::out | ios::app | ios::binary);
inventoryData item;
cout << "Please enter the following data about the item" << endl;
cout << "Description: ";
cin.ignore();
cin.getline(item.desc, DESC_SIZE);
cout << "Quantity: ";
cin >> item.quantity;
cout << "Wholesale cost: ";
cin >> item.wholesale;
cout << "Retail price: ";
cin >> item.retail;
cout << "Date (Please use MO/DA/YEAR format: ";
cin.getline(item.desc, DATE_SIZE);
file.write(reinterpret_cast<char *>(&item), sizeof(item));
return;
}

Program reading from variables stored in itself and not from binary file

I'm working on a program very important to my programming class, and there's something I can't quite figure out; When I try to read from a binary file I've created after opening the program, it fails even if the file's in the directory, and after I try to wipe the contents of the file, I can still 'read' them from the file even though said file is empty when I examine it in explorer. I've determined from this that even though I'm using BinaryFile.read, it's not truly reading from the file, and instead reading from variables stored in the program itself. How can I get my program to read from the actual file?
(please note that this is not yet a complete program, hence the commented sections and empty functions.)
(Also please note that, due to the nature of my class, I am only allowed to use what has been taught already (namely, anything in the fstream header and most things before which are necessary to make a basic program - he's letting me use things in stdio.h, as well.)
//
// main.cpp
// Binary Program
//
// Created by Henry Fowler on 11/19/14.
// Copyright (c) 2014 Bergen Community College. All rights reserved.
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <cstdlib>
#include <math.h>
#include <stdio.h>
using namespace std;
struct Record
{
char Name[20];
char LastName[20];
double Pay;
int Clearance;
int ID;
};
void CreateFile(fstream&); //Working
void CheckExist(fstream&); //Working
void Populate(fstream&,Record[],int&,int&); //Working
void Display(fstream&,Record[],int&,int&); //Working
void Append(fstream&,Record[],int&,int&); //Working
void DeleteFromFile(fstream&,fstream&,Record[],int&,int&);
// void SearchInFile(fstream&,Record[],int&,int&);
// void ModifyRecord(fstream&,Record[],int&,int&);
//void SortFile();
void WipeFile(fstream&);
void DelFile(fstream&);
int main(int argc, const char * argv[])
{
Record EmpRecords[20];
char Binary[] = "BinaryFile.dat";
char Binary2[] = "BinaryFileTemp.dat";
int maxsize; //make sure to set i to max size so you can use it later for things like wiping the file or deleting specific records
fstream BinaryFile;
fstream BinaryFile2;
string InputStr;
// char Read;
//int Choice = 0;
int i = 0;
int choice = 0;
int switchchoice;
CreateFile(BinaryFile); //working
CheckExist(BinaryFile); //working
BinaryFile.close();
while(choice==0)
{
cout << "Options: " << endl;
cout << "End Program (0)" << endl;
cout << "Input new records to file (1)" << endl;
cout << "Display current contents of file (2)" << endl;
cout << "Append a record at the end of the file (3)" << endl;
cout << "Delete a record from the file (4)" << endl;
cout << "Search for a record in the file (5)" << endl;
cout << "Modify a certain record (6)" << endl;
cout << "Sort file (unimplemented)" << endl;
cout << "Wipe contents of file (8)" << endl;
cout << "Please choose an option: ";
cin >> switchchoice;
switch(switchchoice)
{
case 0:
{
cout << "Exiting.";
BinaryFile.close();
system("PAUSE");
return 0;
break;
}
case 1:
{
Populate(BinaryFile, EmpRecords,i,maxsize); //working
break;
}
case 2:
{
Display(BinaryFile, EmpRecords,i,maxsize); //working i think
break;
}
case 3:
{
Append(BinaryFile, EmpRecords,i,maxsize); //working
break;
}
case 4:
{
DeleteFromFile(BinaryFile,BinaryFile2,EmpRecords,i,maxsize); //!
break;
}
case 5:
{
// SearchInFile(BinaryFile, EmpRecords,i,maxsize); //!
break;
}
case 6:
{
// ModifyRecord(BinaryFile, EmpRecords,i,maxsize); //!
break;
}
case 7:
{
cout << "Error, file sorting is currently unimplemented. Please try again.";
break;
}
case 8:
{
WipeFile(BinaryFile);
break;
}
}
}
system("PAUSE");
return 0;
}
void CreateFile(fstream& BinaryFile)
{
BinaryFile.open("BinaryFile.dat", ios::out | ios::binary);
}
void CheckExist(fstream &BinaryFile)
{
if(BinaryFile.good())
{
cout << endl << "File does exist" << endl;
}
else
{
cout << "file named can not be found \n";
system("PAUSE");
}
}
void Populate(fstream &BinaryFile,Record EmpRecords[],int &i, int &maxsize)
{
BinaryFile.open("BinaryFile.dat", ios::out | ios::binary);
int choice = 0;
while(choice==0)
{
cout << "Please input employee first name: ";
cin >> EmpRecords[i].Name;
cout << "Please input employee last name: ";
cin >> EmpRecords[i].LastName;
cout << "Please input Employee Pay: ";
cin >> EmpRecords[i].Pay;
cout << "Please input Employee Clearance (1-10): ";
cin >> EmpRecords[i].Clearance;
cout << "Please input Employee ID (6 numbers, i.e. 122934): ";
cin >> EmpRecords[i].ID;
cout << "Input another employee's information? (0) = yes, (1) = no: ";
cin >> choice;
BinaryFile.write((char *) (&EmpRecords[i]),sizeof(EmpRecords[i]));
i = i+1;
}
maxsize = i;
cout << "i is " << i << endl;
cout << "maxsize is " << maxsize << endl;
BinaryFile.close();
}
void Display(fstream &BinaryFile,Record EmpRecords[],int &i,int &maxsize)
{
BinaryFile.open("BinaryFile.dat", ios::in | ios::binary | ios::app);
int i2 = maxsize;
i = 0;
while(i2>0)
{
BinaryFile.read((char *) (&EmpRecords[i]),sizeof(EmpRecords[i]));
cout << i << endl;
cout << EmpRecords[i].Name << " " << EmpRecords[i].LastName << endl;
cout << "Pay: $" << EmpRecords[i].Pay << endl;
cout << "Clearance: " << EmpRecords[i].Clearance << endl;
cout << "Employee ID: " << EmpRecords[i].ID << endl;
BinaryFile.read((char *) (&EmpRecords[i]),sizeof(EmpRecords[i]));
cout << endl;
i2 = i2-1;
i = i+1;
}
BinaryFile.close();
}
void Append(fstream &BinaryFile,Record EmpRecords[],int &i,int &maxsize)
{
BinaryFile.open("BinaryFile.dat", ios::out|ios::binary|ios::ate|ios::app);
cout << "Please input employee first name: ";
cin >> EmpRecords[maxsize].Name;
cout << "Please input employee last name: ";
cin >> EmpRecords[maxsize].LastName;
cout << "Please input Employee Pay: ";
cin >> EmpRecords[maxsize].Pay;
cout << "Please input Employee Clearance (1-10): ";
cin >> EmpRecords[maxsize].Clearance;
cout << "Please input Employee ID (6 numbers, i.e. 122934): ";
cin >> EmpRecords[maxsize].ID;
cout << "Input another employee's information? (0) = yes, (1) = no: ";
BinaryFile.write((char *) (&EmpRecords[i]),sizeof(EmpRecords[i]));
maxsize = maxsize+1;
cout << "maxsize is " << maxsize << endl;
BinaryFile.close();
}
void DeleteFromFile(fstream &BinaryFile,fstream &BinaryFile2, Record EmpRecords[],int &i,int &maxsize)
{
BinaryFile.open("BinaryFile.dat", ios::out|ios::binary|ios::app);
BinaryFile2.open("BinaryFileTemp.dat", ios::out|ios::binary|ios::app);
int Choice;
cout << "Would you like to delete a file by name or by employee number?" << endl;
cout << "Name (1)" << endl;
cout << "Number (2)" << endl;
cout << "Choice: ";
cin >> Choice;
int i2 = maxsize;
if(Choice==1)
{
cout << "Please input employee first name: ";
// cin >> firstname;
cout << "Please input employee last name: ";
// cin >> lastname;
cout << "Searching...";
int i2 = maxsize;
i = 0;
while(i2>0)
{
BinaryFile.read((char *) (&EmpRecords[i]),sizeof(EmpRecords[i]));
cout << i << endl;
BinaryFile.read((char *) (&EmpRecords[i]),sizeof(EmpRecords[i]));
// if(EmpRecords[i].Name == firstname)
// {
// cout << "Found first name." << endl;
// if (EmpRecords[i].LastName == lastname)
// {
// cout << "Found last name." << endl;
/// }
// }
// else
// {
// cout << "Could not find name.";
// // BinaryFile2.write((char *) (&EmpRecords[i]),sizeof(EmpRecords[i]));
// }
cout << endl;
i2 = i2-1;
i = i+1;
}
}
BinaryFile.close();
if( remove( "BinaryFile.dat" ) != 0 )
cout << endl << "Error deleting file" << endl;
else
{
cout << "File successfully deleted" << endl << endl;
}
int result;
char oldname[]="BinaryFileTemp.dat";
char newname[]="BinaryFile.dat";
result = rename(oldname,newname);
if(result == 0)
cout << "DEBUG: Success" << endl;
else
cout << "DEBUG: Failure" << endl;
}
void WipeFile(fstream &BinaryFile)
{
int sure;
cout << "There is no undoing this action." << endl;
cout << "Continue (1)" << endl;
cout << "Cancel (2)" << endl;
cout << "Wipe file? ";
cin >> sure;
if(sure == 1)
{
cout << "Wiping file.";
BinaryFile.open("BinaryFile.dat", ios::out | ios::binary | ios::trunc);
BinaryFile.close();
}
else
{
cout << "Canceling.";
}
}
void DelFile(fstream &BinaryFile)
{
BinaryFile.close();
if( remove( "BinaryFile.dat" ) != 0 )
cout << endl << "Error deleting file" << endl;
else
{
cout << "File successfully deleted" << endl << endl;
}
}
Here the problem seems to be, even though you are wiping the file contents, you are not clearing the data you had stored in Record EmpRecords[20]; or the int maxsize value.
Few things you can do inside void WipeFile(fstream &BinaryFile) function: To keep it simple, we'll just reset maxsize to 0:
Pass the maxsize variable as reference to WipeFile(), the same way you are passing for Populate()
Update maxsize = 0, to indicate all the records are removed, when you delete the file contents.
It is better to memset the contents of EmpRecords as well similarly.
For now, I just modified your code to reset maxsize to 0 in WipeFile() and it worked.
void WipeFile(fstream &BinaryFile, int &maxsize)
{
int sure;
cout << "There is no undoing this action." << endl;
cout << "Continue (1)" << endl;
cout << "Cancel (2)" << endl;
cout << "Wipe file? ";
cin >> sure;
if(sure == 1)
{
cout << "Wiping file.";
BinaryFile.open("BinaryFile.dat", ios::out | ios::binary | ios::trunc);
BinaryFile.close();
maxsize = 0;
}
else
{
cout << "Cancelling.";
}
}