#ifndef fileVector_H
#define fileVector_H
#include <vector>
#include <fstream>
#include <iomanip>
class fileVector
{private:
const static int nameLen = 25, phoneLen = 16, addLen = 35, eAddLen = 35;
public:
struct Directory
{ char lastName[nameLen], firstName[nameLen];
char address1[addLen], address2[addLen];
char emailAdd[eAddLen];
char phone[phoneLen]; int element;
};
std::vector<Directory>DirV;
Directory Temp; bool newF, failOpen;
std::fstream DirFile;
bool testFile()//
{ failOpen = false;
DirFile.open("Directory.dat", std::ios::in | std::ios::binary);
if (DirFile.fail())//1st attempt to open file
{ DirFile.open("Directory.dat", std::ios::in | std::ios::binary);
if(DirFile.fail())//2nd attempt to open file
{ createFile();//file does not exist, create file
DirFile.open("Directory.dat", std::ios::in | std::ios::binary);
if (DirFile.fail()) failOpen = true;//If fail, there is a problem
else { DirFile.close(); failOpen = false;}//Successfully created file, no read
}//end 2nd attempt
else { failOpen = false; DirFile.close();}//else, 2nd attempt successfuel
}//End if 1st attempt.
else { failOpen = false; DirFile.close(); readFile(); }
//else open file successfully, read into DirV[]
return failOpen;
}//End testFile()
void writeFile()//Assume file is closed, open file to write DirV[] into file.
{ int ct2 = 0;
DirFile.open("Directory.dat", std::ios::out | std::ios::binary);
do
{ DirFile.write(reinterpret_cast<char*>(&(DirV[ct2])),sizeof(DirV[ct2]));
ct2++;
} while (ct2 < DirV.size());
DirFile.close();
}//End of writeFile
void createFile()
{ DirFile.open("Directory.dat", std::ios::out | std::ios::binary | std::ios::app);
DirFile.close();
}
void readFile()//Assume file is OPEN already
{ fileVector::Directory Temp1;
DirFile.open("Directory.dat", std::ios::in | std::ios::binary);
while (!DirFile.eof())
{ DirFile.read(reinterpret_cast<char*>(&(Temp1)), sizeof(Temp1));
if (DirFile.eof()) { break; }
DirV.push_back(Temp1);
}
DirFile.close();
}
void addName(Directory Dir, int& newName)
{ int size, selCase;
DirV.push_back(Dir);//Push to next available element of DirV.
size = DirV.size();// DirV[midPt].element = midPt; newName = midPt;
int startPt = 0, endPt = size - 2, midPt = (endPt - startPt) / 2;
if ((size == 1) || ((strcmp(DirV[endPt].lastName, Dir.lastName) <= 0) & (size >= 2)))
selCase = 0;//Don't have to sort or anything, Dir is in last element already
//Case 0 for first entry when size = 1 OR when Dir.lastName is
// >= to last element of DirV(Dir.lastName >= DirV[endPt].lastName.
else
{ if ((strcmp(Dir.lastName, DirV[startPt].lastName) <= 0) && (size > 1))
selCase = 1;//If Dir smaller than DirV[0] AND (size >1)
else
{ startPt = 0, endPt = size - 2; midPt = (endPt - startPt) / 2;
do { if (strcmp(Dir.lastName, DirV[midPt].lastName) <= 0)
{ endPt = midPt; midPt = (startPt + endPt) / 2;}
else { startPt = midPt; midPt = (startPt + endPt) / 2; }
} while (startPt != midPt);
selCase = 2;
}//else selCase = 2
}//End if((strcmp(Dir.lastName, DirV[startPt].lastName) <= 0) && (size > 1))
switch (selCase)
//(size = 1) AND Dir.lastName => DirV[endPt].lastName
{ case 0: { DirV[size - 1].element = size - 1; newName = size - 1; break; }
case 1://Dir.lastName <= DirV[0].lastName
{ int i;
for (i = 1; i <= (size - 1); i++)
{ DirV[size - i] = DirV[size - i - 1];
DirV[size - i].element = size - i;
DirV[size - i - 1].element = size - i - 1;
}//End for
DirV[size - i] = Dir; newName = size - i;
DirV[size - i].element = size - i;
break;
};//End case 1
case 2:
{ int j;
for (j = 1; j <= (size - endPt - 1); j++)
{ DirV[size - j] = DirV[size - j - 1];
DirV[size - j].element = size - j;
DirV[size - j - 1].element = size - j - 1;
}
DirV[size - j] = Dir; newName = size - j;
DirV[size - j].element = size - j;
break;
};//end case 2
};//End switch
}
void sort_firstName(int& newName)//DirV[newName] is the newly added name.
{ int beginLname = newName, endLname = newName;//start out all equal
int bubbleDown, bubbleUp;
Temp = DirV[newName];//Temporary structure variable
bool doneUp = false, doneDown = false, moveUp = false;
bubbleUp = newName; bubbleDown = newName;
while ((bubbleUp > 0) & !doneUp)//Prevent bubbleUp going negative
{if ((strcmp(DirV[newName].lastName, DirV[newName - 1].lastName) == 0)
& (strcmp(DirV[newName].firstName, DirV[newName - 1].firstName) < 0))
{ DirV[newName] = DirV[newName - 1]; DirV[newName].element = newName;
DirV[newName - 1] = Temp; DirV[newName - 1].element = newName - 1;
newName--; bubbleUp--; moveUp = true;
}
else (doneUp = true);
}//END while((bubbleUp > 0)& !doneUp)
if (moveUp == false)
{ while ((bubbleDown < (DirV.size() - 1)) & !doneDown)
{ if ((strcmp(DirV[newName].lastName, DirV[newName + 1].lastName) == 0)
& (strcmp(DirV[newName].firstName, DirV[newName + 1].firstName) > 0))
{ DirV[newName] = DirV[newName + 1]; DirV[newName].element = newName;
DirV[newName + 1] = Temp; DirV[newName + 1].element = newName + 1;
newName++; bubbleDown++;
}
else doneDown = true;
}//END while (decrement < bubbleUp)
}
}
void showRange(char selName[25])
{ int size = DirV.size(), stpt = 0, edpt = size - 1;
int mdpt = (stpt + edpt) / 2, index, comp;
do //search to within range using 2 characters in selName
{ comp = strncmp(selName, DirV[mdpt].lastName, 2);
if (comp != 0)
{ if (comp > 0) { stpt = mdpt; mdpt = (stpt + edpt) / 2; }
else { edpt = mdpt; mdpt = (stpt + edpt) / 2; }
}
} while ((comp != 0) && (stpt + 2 <= edpt));//Matching DirV[mdpt]
for (index = -2; index <= 3; index++)
{ if (((mdpt + index) >= 0) && ((mdpt + index) <= (size - 1)))
{std::cout << " Element #" << DirV[mdpt + index].element <<
"] is: Last name: " << std::left << std::setw(10) << DirV[mdpt + index].lastName <<
" first name: " << std::left << std::setw(10) << DirV[mdpt + index].firstName << "\n\n";
}
}//End for loop to display range of names if it is valid.
}//End showRange
void deleteName(int numDelete)
{ char sure;
int edpt = DirV.size() - 1;
std::cout << " Is this what you chose?\n";
std::cout << " Element #" << DirV[numDelete].element <<
"] is: Last name: " << std::left << std::setw(10) << DirV[numDelete].lastName <<
" first name: " << std::left << std::setw(10) << DirV[numDelete].firstName << "\n\n";
std::cout << " Are you sure you want to delete this:\n\n"; std::cin >> sure;
if (tolower(sure) == 'y')
{ for (int i = 0; i < (edpt - numDelete); i++)
{ DirV[numDelete + i] = DirV[numDelete + i + 1];
DirV[numDelete + i].element = numDelete + i;
}
DirV.pop_back();
}
}
};
#endif