I have to code, build, and execute a program that requires sequential files to create an address database. The program works but When I re-run the program the old data is still in the database when I chose to display records. How do I get the program to erase old data and start fresh when I start the program from the beginning. Can you please help identify my errors. Thank you in advance.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void menu(void);
void writeData(void);
void readData(void);
string * split(string, char);
const char FileName[] = "TestAddress.txt"; //File name from where to read the characters
int main()
{
menu();
return 0;
}
void menu(void)
{
//Display main menu and call relevant functions
char input;
while (1)
{
//allow user to choose to append records, display records or exit the program
cout << "Select program\n(A)ppend Records, (D)isplay Records, (E)xit: ";
cin >> input;
cout << endl;
if (input == 'A' || input == 'a')
writeData();//Append data to the file
else if (input == 'D' || input == 'd')
readData(); //Read records from the file and display
else if (input == 'E' || input == 'e')
exit(0);// Exit application
else
cout << endl << "Invalid Input!!! Please enter A, D or E:" << endl; //In case of invalid input, menu will be displayed again
}
}//end menu
void writeData(void) {//Append data to the file
string fullName, Street, City, State, ZipCode, input;
fstream outputFile;
outputFile.open(FileName, fstream::app); //Open the file with append mode
do {
cout << endl;
cout << "Please enter Name: ";
cin.ignore();
getline(cin, fullName); //Input Name
cout << "Please enter Street: ";
cin.ignore();
getline(cin, Street); //Input Street Address
cout << "Please enter City: ";
cin >> City; //Input City
cout << "Please enter State: ";
cin >> State;// Input State
cout << "Please enter ZipCode: ";
cin >> ZipCode; //Input Zipcode
cout << endl;
outputFile << fullName << "," << Street << "," << City << "," << State << "," << ZipCode << endl; //Write all data to the file
do
{
cout << "Enter Another Record?(Y/N): ";
cin >> input;//In case if user wants to enter another rcord
}
while (input != "Y"&& input != "y" && input != "N"&& input != "n"); //Until the user presses 'y' or 'n'
} while (input == "Y" || input == "y"); //If user wants to add another record continue or else display menu again
outputFile.close(); //Close file
}//end write data
void readData(void) {//Read records from the file and display
string Name, Street, City, State, ZipCode;
char* line = new char[2000]; //pointing to a vriable that will be having a record detail
ifstream inputFile;
int RecordNumber = 1;
inputFile.open(FileName, fstream::in);//Open the file with read mode
while (!inputFile.eof())
{
inputFile.getline(line, 2000); //Read one record from the file
string * fields = split(line, ',');//Split the records based on the prsence of ','
if (fields[0] == "") //In case of '\n' has encountered
continue; //Stop processing and continue the loop again
cout << "" << endl;
cout << "Record #" << RecordNumber << endl; //Displaying record with style
cout << "Name.........." << fields[0] << endl;
cout << "Street........" << fields[1] << endl;
cout << "City.........." << fields[2] << endl;
cout << "State........." << fields[3] << endl;
cout << "Zip Code......" << fields[4] << endl;
cout << endl << "-------------------------------------------------------" << endl << endl;
RecordNumber++; //Increment record number
}
}//end read data
string * split(string theLine, char theDeliminator) {
//determine how many splits there will be so we can size our array
int splitCount = 0;
for (int i = 0; i < theLine.size(); i++)
{
//Read the whole string (theLine) and count for all ',' encountered
if (theLine[i] == theDeliminator)
splitCount++;
}
splitCount++; //add one more to the count because there is not an ending comma
//create an array to hold the fields
string* theFieldArray;
theFieldArray = new string[splitCount];
//split the string into seperate fields
string theField = "";
int commaCount = 0;
for (int i = 0; i < theLine.size(); i++)
{
//read each character and look for the deliminator
if (theLine[i] != theDeliminator) {
theField += theLine[i]; //build the field
}
else { //the deliminator was hit so save to the field to the array
theFieldArray[commaCount] = theField; //save the field to the array
theField = "";
commaCount++;
}
}
theFieldArray[commaCount] = theField; //the last field is not marked with a comma...
return theFieldArray;
} //end split
Related
Ok. I'm trying to finish writing to a file and then reading from a file but I keep getting an error when I start the void readData(void).The error is "no matching token found." What could I do to make this work/ make it easier?
I'm not understanding how to use the void function, I think. I'm sure there are more issues because when I remove void readData(void) the error moves to void writeData(void).
//Specification: Append and display records in a address database
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void menu(void);
void writeData(void);
void readData(void);
ifstream infile;
string cont = "Y";
string name;
string street;
string city;
string state;
string zip;
string choice;
const char FileName[] = "TestAddress.txt";
ofstream outfile("TestAddress.txt", ios::app);
int main() {
menu();
writeData();
readData();
return 0;
} //end main
void menu(void) {
cout << "Would you like to add to the records, display them, or exit?\n";
cout << "Enter a to add, d to display, or e to exit";
cin >> choice;
}
//allow user to choose to append records, display records or exit the program
//end menu
void writeData(void) {
while (choice != "a") {
cout << "Enter the address name: ";
getline(cin, name);
cout << "Enter the house number and street: ";
cin >> street;
cout << "Enter the city: ";
cin >> city;
cout << "Enter the state: ";
cin >> state;
cout << "Enter the zip code: ";
cin >> zip;
outfile << name << "#" << street << city << "#" << state << "#" << zip << endl;
cin.ignore();
cout << "Do you want add another addressor exit? (a/e)";
getline(cin, choice);
}
outfile.close();
//Write the Address Info to a file
//loop while user still has data to write to file
//eg outStream<<name<<”#”; //where # is the delimiter
}
//end write data
void readData(void) {
//read data from a file
//use the split function to break a
//deliminated line of text into fields
infile.open("TestAddress.txt");
ifstream inMyStream("TestAddress.txt");
while (choice != "d") {
if (inMyStream.is_open()) {
//set character to use as a line between record displays
string recBreaks = "#";
recBreaks.assign(20, '#');
int fieldCount = 0; //keep track of the number of fields read
int recordCount = 1; //keep track of the number of records read
//read the first field
fieldCount = 1;
string fieldBuffer;
getline(inMyStream, fieldBuffer, '#');
while (!inMyStream.eof()) {
//display the field
switch (fieldCount) {
case 1:
cout << recBreaks << endl;
cout << "record # " << recordCount << endl;
cout << "Name...." << fieldBuffer << endl; break;
case 2:
cout << "Street.." << fieldBuffer << endl; break;
case 3:
cout << "City...." << fieldBuffer << endl; break;
case 4:
cout << "State..." << fieldBuffer << endl; break;
case 5:
cout << "Zip....." << fieldBuffer << endl;
fieldCount = 0;
recordCount++; break;
}
//read the next field
getline(inMyStream, fieldBuffer, '#');
fieldCount++;
}
cout << recBreaks << endl;
inMyStream.close();
}//end read data
}
My program basically ask user for inputs and it saves data like login data, username in a text file and uses same file to retrieve data and displays in the output console. When program executes users can choose between options 1 to 6, option 6 is for existing out of the application and rest of the options from 1 to 5 are for users to input data and to view stored data in the file.
When program displays data in the console, I see lots of unnecessary ASCii code. Why is it showing up and how do I make them go ? Thanks!!
int main() {
//Considering the max length of data entered (name) to be 15.
char data[15];
int n = 0, option = 0, count_n = 0;
//This is the initial mark alloted to a subject.
string empty = "00";
string proctor = "";
//Name of the file in which DB is stored.
ifstream f("Example.txt");
string line;
//The following for loop counts the total number of lines in the file.
for (int i = 0; std::getline(f, line); ++i) {
count_n++;
}
while (option != 6) {
//This prints out all the available options in the DB
cout << "\nAvailable operations: \n1. Add New Students\n2."
<< "Student Login\n3. Faculty Login\n4. Proctor Login\n5. Admin View\n"
<< "6. Exit\nEnter option: ";
cin >> option;
if (option == 1) {
cout << "Enter the number of students: ";
cin >> n;
count_n = count_n + n;
for (int i = 0; i < n; i++) {
ofstream outfile;
outfile.open("Example.txt", ios::app);
//The entire data of a single student is stored line-by-line.
cout << "Enter your registration number: ";
cin >> data;
outfile << data << "\t";
cout << "Enter your name: ";
cin >> data;
int len = strlen(data);
while (len < 15) {
data[len] = ' ';
len = len + 1;
}
outfile << data << "\t";
//Inserting empty data initially into the file
outfile << empty << "\t";
outfile << empty << "\t";
cout << "\b \b";
cout << "Enter your proctor ID: ";
cin >> proctor;
outfile << proctor << endl;
}
}
else if (option == 2) {
char regno[9];
cout << "Enter your registration number: ";
cin >> regno;
ifstream infile;
int check = 0;
infile.open("Example.txt", ios::in);
//This loop prints out the data according to the registration number specified.
while (infile >> data) {
if (strcmp(data, regno) == 0) {
cout << "\nRegistration Number: " << data << endl;
infile >> data;
cout << "Name: " << data << endl;
infile >> data;
cout << "CSE1001 mark: " << data << endl;
infile >> data;
cout << "CSE1002 mark: " << data << endl;
infile >> data;
cout << "Proctor ID: " << data << endl;
infile.close();
check = 1;
}
}
if (check == 0) {
cout << "No such registration number found!" << endl;
}
}
//This loop is used to view and add marks to the database of a student.
else if (option == 3) {
char subcode[7];
cout << "Enter your subject code: ";
cin >> subcode;
string code1 = "CSE1001", code2 = "CSE1002", mark = "";
ifstream infile;
int check = 0;
cout << "\nAvailable operations: \n1. Add data about marks\n"
<< "2. View data\nEnter option: ";
cin >> option;
if (option == 1) {
cout << "Warning! You would need to add mark"
<< "details for all the students!" << endl;
for (int i = 0; i < count_n; i++) {
fstream file("Example.txt");
//The seek in file has been done according to the length
//of the data being inserted. It needs to adjusted accordingly
//for diffferent lengths of data.
if (strcmp(subcode, code1.c_str()) == 0) {
file.seekp(26 + 37 * i, std::ios_base::beg);
cout << "Enter the mark of student#" << (i + 1) << " : ";
cin >> mark;
file.write(mark.c_str(), 2);
}
if (strcmp(subcode, code2.c_str()) == 0) {
file.seekp(29 + 37 * i, std::ios_base::beg);
cout << "Enter the mark of student#" << (i + 1) << " : ";
cin >> mark;
file.write(mark.c_str(), 2);
}
}
}
//This loop is used to view marks of a student.
//The extra infile commands have been used to get a specific mark
//only since the data has been seperated by a tabspace.
else if (option == 2) {
infile.open("Example.txt", ios::in);
if (strcmp(subcode, code1.c_str()) == 0) {
cout << "Registration number - Marks\n" << endl;
while (infile >> data) {
cout << data;
infile >> data;
infile >> data;
cout << " - " << data << endl;
infile >> data;
infile >> data;
check = 1;
}
}
infile.close();
infile.open("Example.txt", ios::in);
if (strcmp(subcode, code2.c_str()) == 0) {
cout << "Registration number - Marks\n" << endl;
while (infile >> data) {
cout << data;
infile >> data;
infile >> data;
infile >> data;
cout << " - " << data << endl;
infile >> data;
check = 1;
}
}
}
infile.close();
if (check == 0) {
cout << "No such subject code found!" << endl;
}
}
//This loop displays all the details of students under the same proctor ID.
else if (option == 4) {
char procid[7];
cout << "Enter your proctor ID: ";
cin >> procid;
int check = 1;
char temp1[100], temp2[100], temp3[100];
char temp4[100], id[100];
ifstream infile;
infile.open("Example.txt", ios::in);
while (infile >> temp1) {
infile >> temp2;
infile >> temp3;
infile >> temp4;
infile >> id;
if (strcmp(id, procid) == 0) {
cout << "\nRegistration Number: " << temp1 << endl;
cout << "Name: " << temp2 << endl;
cout << "CSE1001 Mark: " << temp3 << endl;
cout << "CSE1002 Mark: " << temp4 << endl;
check = 1;
}
}
if (check == 0) {
cout << "No such proctor ID found!" << endl;
}
}
//This loop acts as an admin view to see all the data in the file.
else if (option == 5) {
char password[25];
cout << "Enter the admin password: ";
cin >> password;
//This variable value can be changed according to your requirement
//of the administrator password.
string admin_pass = "admin";
if (strcmp(password, admin_pass.c_str()) == 0) {
cout << "Reg No. \tName\tCSE1001\tCSE1002\tProctor ID" << endl;
ifstream infile;
infile.open("Example.txt", ios::in);
char data[20];
while (infile >> data) {
cout << data << "\t";
infile >> data;
cout << data << "\t";
infile >> data;
cout << data << "\t";
infile >> data;
cout << data << "\t";
infile >> data;
cout << data << endl;
}
}
}
}
}
Here is the output:
The ╠ character is a box drawing character. In code page 437 it is represented by hex value 0xCC.
In this case it is a magic hex value that means it is uninitialised stack memory.
The data array is 20 characters long, but it degrades into a pointer and the operator<< outputs characters until it gets a null character. So in this case lots of uninitialized memory ╠ characters until a \0 character is found in memory.
It seems that the uninitialized data variable was written to the file on a previous run and now it is read back as-is. If the read was unsuccessful it would probably have placed a \0 in the first position of the data char array and there would have been no output in that case.
I ran the program with an empty input file and added a single student. This was stored in the text file (viewed with Visual Studio's text editor):
REGNUM123 Pete ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ 00 00 PROC432
In this case Ì, or latin capital letter i with grave character is the 0xCC hex value in Unicode and multiple other encodings. When adding the student the number of characters written does not necessarily equal the number of characters in the data array (15 in that case). They are written until a \0 is found.
Most probably you have multiple buffer overruns:
char password[25];
cout << "Enter the admin password: ";
cin >> password;
If someone inputs more than 24 bytes (characters) as a password, you will have buffer overrun of password. You should do it this way:
std::string password;
cout << "Enter the admin password: ";
cin >> password;
The same thing is valid for output, you're potentially buffer overrunning char data[20];. Furthermore, you can't use infile >> data like that for reading from file. You have to use infile.getline():
int col_count = 4;
while (true) {
infile.getline(data, 20); // 20 is the size of the buffer.
if(infile.good()) {
cout << data;
if(--col_count == 0) {
col_count = 4;
cout << '\n';
}
else cout << '\t';
}
else break;
}
Hello everyone I have been working on my lab for a few days now and I think I am close to completion. However when I go to build my program I keep getting the errors unresolved external symbol main reference in function int cdecl. Its also giving me the error of 1 unresolved externals. I am not sure what this means since I am new to writing in C++ and any help would be greatly appreciated.
Here is what I have so far
enter code here
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void menu(void);
void writeData(void);
void readData(void);
string * split(string, char);
const char FileName[] = "TestAddress.txt"; //File name from where to read the characters
int _tmain()
{
menu();
return 0;
}
void menu(void) { //Display main menu and call relevant functions
char input;
while (1)
{
cout << endl;
cout << "|---------------------MENU----------------------------|" << endl; //Menu display with style
cout << "| (A)ppend Records, (S)how Records, (E)xit |" << endl; //3 options that can be selected
cout << "|-----------------------------------------------------|";
cout << endl << endl;
cin >> input;
if (input == 'A' || input == 'a')
writeData();//Append data to the file
else if (input == 'S' || input == 's')
readData(); //Read records from the file and display
else if (input == 'E' || input == 'e')
exit(0);// Exit application
else
cout << endl << "Invalid Input!!! Please try again." << endl << endl; //In case of invalid input, menu will be displayed again
}
}//end menu
void writeData(void) {//Append data to the file
string Name, Street, City, State, ZipCode, input;
fstream outputFile;
outputFile.open(FileName, fstream::app); //Open the file with append mode
do {
cout << endl << endl;
cout << "Please enter Name:" << endl;
cin >> Name; //Input Name
cout << endl;
cout << "Please enter Street:" << endl;
cin >> Street;//Input Street Address
cout << endl;
cout << "Please enter City:" << endl;
cin >> City; //Input City
cout << endl;
cout << "Please enter State:" << endl;
cin >> State;// Input State
cout << endl;
cout << "Please enter ZipCode:" << endl;
cin >> ZipCode; //Input Zipcode
cout << endl;
cout << endl;
outputFile << Name << "," << Street << "," << City << "," << State << "," << ZipCode << endl; //Write all data to the file
//Displaying the record which is input recently fromt he user
cout << endl; //Displaying heading with style
cout << "|-----------------------------------------------------|" << endl;
cout << "| Append Records |" << endl;
cout << "|-----------------------------------------------------|" << endl << endl;
cout << "Name.........." << Name << endl;
cout << "Street........" << Street << endl;
cout << "City.........." << City << endl;
cout << "State........." << State << endl;
cout << "Zip Code......" << ZipCode << endl;
cout << endl << endl;
do {
cout << "Enter Another Record?(Y/N)" << endl;
cin >> input;//In case if user wants to enter another rcord
} while (input != "Y"&& input != "y" && input != "N"&& input != "n"); //Until the user presses 'y' or 'n'
} while (input == "Y" || input == "y"); //If user wants to add another record continue or else display menu again
outputFile.close(); //Close file
}//end write data
void readData(void) {//Read records from the file and display
string Name, Street, City, State, ZipCode;
char* line = new char[2000]; //pointing to a vriable that will be having a record detail
ifstream inputFile;
int RecordNumber = 1;
inputFile.open(FileName, fstream::in);//Open the file with read mode
cout << endl;
cout << "|-----------------------------------------------------|" << endl; //Heading display with style
cout << "| Show Records |" << endl;
cout << "|-----------------------------------------------------|";
while (!inputFile.eof())
{
inputFile.getline(line, 2000); //Read one record from the file
string * fields = split(line, ',');//Split the records based on the prsence of ','
if (fields[0] == "") //In case of '\n' has encountered
continue; //Steop processing and continue the loop again
cout << "" << endl;
cout << "Record #" << RecordNumber << endl; //Displaying record with style
cout << "Name.........." << fields[0] << endl;
cout << "Street........" << fields[1] << endl;
cout << "City.........." << fields[2] << endl;
cout << "State........." << fields[3] << endl;
cout << "Zip Code......" << fields[4] << endl;
cout << endl << "-------------------------------------------------------" << endl << endl;
RecordNumber++; //Increment record number
}
}//end read data
string * split(string theLine, char theDeliminator) {
//determine how many splits there will be so we can size our array
int splitCount = 0;
for (int i = 0; i < theLine.size(); i++) { //Read the whole string (theLine) and count for all ',' encountered
if (theLine[i] == theDeliminator)
splitCount++;
}
splitCount++; //add one more to the count because there is not an ending comma
//create an array to hold the fields
string* theFieldArray;
theFieldArray = new string[splitCount];
//split the string into seperate fields
string theField = "";
int commaCount = 0;
for (int i = 0; i < theLine.size(); i++) { //read each character and look for the deliminator
if (theLine[i] != theDeliminator) {
theField += theLine[i]; //build the field
}
else { //the deliminator was hit so save to the field to the array
theFieldArray[commaCount] = theField; //save the field to the array
theField = "";
commaCount++;
}
}
theFieldArray[commaCount] = theField; //the last field is not marked with a comma...
return theFieldArray;
} //end split
Hello I am having issues with a final project. The objective is to have the user create a form that allows a user to view data, edit data, add data, and save their password data in an encoded format. The program starts with an input file made by the user. The delimiter is ';', and the first char is a "code", then the, site, username, password, and notes follow.
I am very new to vectors, and I am not allowed to use a 2d array, or map.
Thank you for your time.
#include <iomanip>
#include <cmath>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
const int MAX_SIZE = 30;
const int BUFFER_SIZE = 200;
struct dataRow {
string site, user, pass, notes;
string code;
};
string inFileName; //name of inputfile
string outFileName;
ifstream pathStream;
ofstream outFile;
char inputChar;
int extPosition(1), count = 0,lineNum;
void displayVector(vector<dataRow> inputData);
void viewLineData(vector<dataRow> inputData, int lineNum);
void addNewRow(vector<dataRow> inputData,int& lastRowNum, string site, string user, string pass, string notes);
void editLineData(vector<dataRow> inputData, int& lineNum, string site, string user, string pass, string notes);
void warning();
void cleanBuffer();
bool displayMenu();
int exit();
dataRow descripLine;
int main()
{
vector<dataRow> inputData;
string rowDescripin,userin,passin,notesin,sitein;
string codein,errorMsg;
int lastRow;
//add a .txt extension to the file if the user didn't provide an extension
if (inFileName.size() > 4)
// If there's a valid extension, it will be in the last 4 positions of the string; Adjust by 1 for 0 offset
extPosition = inFileName.size() - 4;
int ext = inFileName.find_last_of(".txt");
if (!(inFileName.find_last_of(".") == extPosition))
{
inFileName += ".txt";
}
cout << "\nPlease enter the filename of input file: ";
cin >> inFileName;
pathStream.open(inFileName.c_str());
if (pathStream.fail())
{
cerr << inFileName << " failed to open.\n";
system("pause");
exit(1);
}
else
{
cout << "startup success" << endl;
}
getline(pathStream, codein, ';');
descripLine.code = codein;
while (!pathStream.eof())
{
getline(pathStream, sitein, ';');
descripLine.site = sitein;
getline(pathStream, userin, ';');
descripLine.user = userin;
getline(pathStream, passin, ';');
descripLine.pass = passin;
getline(pathStream, notesin, ';');
descripLine.notes = notesin;
inputData.push_back(descripLine);
}
displayVector(inputData);
displayMenu();
while (cin){
cin >> inputChar;
inputChar = toupper(inputChar);
//Adjust calculations based on inputCHar
if (inputChar == 'D') // Display line descriptions
{
displayVector(inputData);
}
else if (inputChar == 'V') //View line data
{
cout << "Enter line number you wish to view: ";
cin >> lineNum;
viewLineData(inputData, lineNum);
}
/* else if (inputChar == 'E') //Edit line Data
{
cout << "Enter line number you wish to edit: ";
cin >> lineNum;
editLineData(inputData, lineNum);
}*/
else if (inputChar == 'A') //Add line data
{
warning();
lastRow = inputData.size();
cout << "Enter a line description: ";
cin >> rowDescripin;
cout << "Enter a line username: ";
cin >> userin;
cout << "Enter a line password: ";
cin>>passin;
cout << "Enter notes: ";
cin>>notesin;
addNewRow(inputData, lastRow, rowDescripin, userin, passin, notesin);
}
/*else if (inputChar == 'S') //Save and encode file
{
}*/
else if (inputChar == 'X') //exit program
{
exit();
}
}
system("pause");
}
bool displayMenu()
{
cout << endl << " AVAILABLE OPTIONS " << endl << endl <<
"D - DISPLAY LINE DESCRIPTIONS" << endl <<
"V - VIEW LINE DATA" << endl <<
"E - EDIT LINE DATA" << endl <<
"A - ADD LINE DATA" << endl <<
"S - SAVE AND ENCODE FILE" << endl <<
"X - EXIT PROGRAM" << endl;
return 0;
}
void viewLineData(vector<dataRow> inputData,int lineNum)
{
cout << inputData[lineNum].site << endl << inputData[lineNum].user<<endl<<inputData[lineNum].pass <<endl<<inputData[lineNum].notes;
}
void displayVector(vector<dataRow> inputData)
{
cout << fixed << setprecision(3);
for (unsigned int i = 0; i < inputData.size(); i++)
{
cout << left << setw(20) << inputData[i].site ;
}
}
void addNewRow(vector<dataRow> inputData, int& lastRowNum, string site, string user, string pass, string notes)
{
char ans;
cout << "You have entered:" << endl << site << endl << user << endl << pass << endl << notes<<endl;
cout << "Is this the data you wish to add (Y/N)? ";
cin >> ans;
ans = toupper(ans);
if (ans == 'Y')
{
dataRow tempRow = { site, user, pass, notes };
inputData.push_back(tempRow);
cout << inputData.size();
int num = inputData.size()-1;
for (unsigned int i = 0; i < inputData.size(); i++)
{
cout << inputData[i].site << endl << inputData[i].user << endl << inputData[i].pass << endl << inputData[i].notes;
}
}
else if (ans == 'N')
{
cout << "ok enter of no";
}
}
void warning()
{
cout<< "WARNING: You cannot use semi-colons in these fields. Any semi-colons entered will be removed." << endl;
return;
}
int exit()
{
pathStream.close();
system("pause");
return 0;
}
void cleanBuffer()
{
cin.clear();
cin.ignore(BUFFER_SIZE, '\n');
}
thanks for your anticipated help. I have been looking at this code for hours and days but I just cant seem to find out why my delRecFunc() isn't deleting just one record at a time. It appears it is deleting the whole file.
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <string>
#include <iomanip>
using namespace std;
const int NAME_SIZE = 40, ADDR_SIZE = 50, PHONE_SIZE = 14;
char y, Y;
struct Info
{
char name[NAME_SIZE];
int age;
char address1[ADDR_SIZE];
char phone[PHONE_SIZE];
}people;
void popFunc();
void dispFunc();
void appFunc();
void delRecFunc();
void searchFunc();
void modRecFunc();
int getNumRec();
int validateRecord (int);
void wipeFunc();
int main()
{
Info person;
char choice, option;
cout << " The file we are working with is named stuff.dat,\n"
<< "I will let you know if it unavailable " << endl;
cout << " "<< endl;
do
{
cout << " \n \n Simple People Records... \n \n \n "
<< " Please choose from the following options: \n \n \n"
<< " 1. POPULATE THE BINARY FILE \n"
<< " 2. DISPLAY THE CONTENTS OF THE FILE\n"
<< " 3. APPEND A RECORD TO THE FILE\n"
<< " 4. DELETE A RECORD FROM THE FILE\n"
<< " 5. SEARCH FOR A CERTAIN RECORD\n"
<< " 6. MODIFY A CERTAIN RECORD. \n"
<< " 7. WIPE OUT THE ENTIRE CONTENTS OF THE FILE. \n" <<endl;
cin >> option;
switch(option)
{
case '1': popFunc();
system("pause");
break;
case '2': dispFunc();
break;
case '3': appFunc();
break;
case '4': delRecFunc();
break;
case '5':searchFunc();
break;
case '6':modRecFunc();
break;
case '7':wipeFunc();
break;
}
}
while(choice!= 1000);
system("pause");
return(0);
}
void popFunc()
{ fstream file("stuff.dat", ios::out | ios::binary);
if (file.fail())
{
cout << "the file does not exist so we are creating it now... ";
system("pause");
file.open("stuff.dat", ios::out);
}
cout << "enter the following data about a person: "<<endl;
cout << "Name: " <<endl;
cin >> ws;
cin.getline(people.name,NAME_SIZE);
cout << "Age (integers only or the program will be corrupted): " <<endl;
cin >> people.age;
cin.ignore(); //skip over the remaining newline.
cout<< "Address line 1: ";
cin >> ws;
cin.getline(people.address1,ADDR_SIZE);
cout << "Phone: in the following format ie: 201.123.1234 (no hyphens)";
cin >> ws;
cin.getline(people.phone,PHONE_SIZE);
file.write(reinterpret_cast<char *>(&people), sizeof(people));
file.close();
}
void dispFunc()
{
ifstream file;
file.open("stuff.dat", ios::binary);
if (file.fail())
{
cout << "the file does not exist so we are creating it now... ";
system("pause");
file.open("stuff.dat", ios::out);
}
while(file.read(reinterpret_cast<char *> (&people), sizeof(people)))
{
cout << "Name: "<< people.name <<endl;
cout << "Age: "<< people.age <<endl;
cout << "Address: " <<people.address1 <<endl;
cout << "Phone #: " <<people.phone << " \n\n"<<endl;
}
file.close();
}
void appFunc()
{ ofstream file;
file.open("stuff.dat", ios::binary | ios::app);
if (file.fail())
{
cout << "the file does not exist so we are creating it now... ";
system("pause");
file.open("stuff.dat", ios::out);
}
cout << "Name: " <<endl;
cin >> ws;
cin.getline(people.name,NAME_SIZE);
cout << "Age (integers only or the program will be corrupted): " <<endl;
cin >> people.age;
cin.ignore(); //skip over the remaining newline.
cout<< "Address line 1: ";
cin >> ws;
cin.getline(people.address1,ADDR_SIZE);
cout << "Phone: Phone: in the following format ie: 201.123.1234 (no hyphens)";
cin >> ws;
cin.getline(people.phone,PHONE_SIZE);
file.write(reinterpret_cast<char *>(&people), sizeof(people));
file.close();
}
void searchFunc()
{
int count =1;
int answer;
long recNum;
int recCount = getNumRec();
fstream search;
search.open("stuff.dat", ios::in | ios:: binary);
cout << " Please enter 1 - " <<recCount ;
cout << " and I will display the data /n"<<endl;
cin >>recNum;
while(recNum<1 || recNum > recCount)
{
cout<<"Please enter a number between 1 and "<<recCount<<": ";
cin>>recNum;
}
answer = validateRecord(recNum);
}
void modRecFunc()
{
int count=1;
int answer;//to hold choice from the user
long recNum;//to hold a record number
int recCount = getNumRec();//variable to hold how many record the file has
fstream search;
//open file
search.open("stuff.dat",ios::in|ios::out|ios::binary);
cout<<"Which record do you wish to edit? ";
cin>>recNum;//variable to store the record the user wish to delete
//validation so the user is not allow to enter more numbers than the actual
//size of the file
while(recNum<1||recNum>recCount)
{
cout<<"Please enter a number between 1 and "<<recCount<<": ";
cin>>recNum;
}
//move pointer to desire position
cout<<endl;
answer= validateRecord(recNum);//make sure the record is the right one
cout<<endl;
if(answer==1)
{
//get the new data
cout << "Name: " <<endl;
cin >> ws;
cin.getline(people.name,NAME_SIZE);
cout << "Age (integers only or the program will be corrupted): " <<endl;
cin >> people.age;
cin.ignore(); //skip over the remaining newline.
cout<< "Address line 1: ";
cin >> ws;
cin.getline(people.address1,ADDR_SIZE);
cout << "Phone: Phone: in the following format ie: 201.123.1234 (no hyphens)";
cin >> ws;
cin.getline(people.phone,PHONE_SIZE);
search.seekp((recNum-1)*sizeof(people), ios::beg);
search.write(reinterpret_cast<char *>(&people), sizeof(people));
}
cout<<endl;
search.close();
}
void wipeFunc()
{ char option;
ofstream file;
cout << "This option will delete all the contents of the file "<<endl;
cout << " Are you sure you want to delete the file? Y or N " <<endl;
cin >> option;
if (option == 'y' || option == 'Y')
{
cout << " Warning, if you hit Y, you will lose everything " <<endl;
cout << " Y to confirm, N to return to main menu" <<endl;
cin >> option;
if(option == 'y' || option == 'Y')
{
file.open("stuff.dat", ios::out | ios::binary);
file.close();
}
}
}
int validateRecord (int recNum)
{
int answer;// variable to hold the answer from the user
fstream validate;
//open file
validate.open("stuff.dat",ios::in|ios::out|ios::binary);
validate.seekg((recNum-1)*sizeof(people));
//read record from file
validate.read(reinterpret_cast<char*>(&people),sizeof(people));
cout<<endl;
cout << "the name is "<< people.name <<endl;
cout << "the age is "<< people.age <<endl;
cout << "the address is" <<people.address1 <<endl;
cout << "the phone is Phone: " <<people.phone <<endl;
cout<<"Is this the file you want?\n"
"1. yes\n"
"2. no\n"
"Choice: ";
cin>>answer;
// validate answer to 1 or 2
while(answer<1||answer>2)
{
cout<<"enter only 1 or 2: ";
cin>>answer;
}
cout<<endl;
validate.close();
return answer;
}
int getNumRec()
{
int count =0;
fstream file;
file.open("stuff.dat", ios::in|ios::binary);
if (file.fail())
{
cout << "Error opening file. Program aborting.\n";
}
file.read(reinterpret_cast<char *>(&people),sizeof(people));
while (!file.eof())
{
count++;
file.read(reinterpret_cast<char *>(&people),
sizeof(people));
}
file.close();//close the file
return count;//return count the erase function
}
void delRecFunc()
{
int count=1;
int answer; //to hold choice from the user
double recNum;//to hold the record number the user wishes to delete
int recCount = getNumRec();//variable to hold how many record the file has
fstream erase;
erase.open("stuff.dat", ios::in|ios::out|ios::binary);
Info Temp; //*****NEW TEMP STRUCT VAR*****//
cout << "Please enter the phone number of the person you want to delete in this
format 201.123.1111)";
cin >> recNum;
//move pointer to desire position
erase.seekg((recNum-1)*sizeof(people));
//read record from file
erase.read(reinterpret_cast<char*>(&people),sizeof(people)); //read record from file
//get answer from the validateRecord function
answer = validateRecord (recNum);
if(answer == 1)
{
ofstream copy;
copy.open("stuff2.dat", ios::out | ios::binary);
erase.seekg(0*sizeof(people)); // Move pointer to beginning of the file
erase.read(reinterpret_cast<char*>(&people),sizeof(people));
// BEGIN NEW CODE //
// Keep looping till there are no more records in the customer.dat file
while (!erase.eof())
{
// If the id that the user wants deleted doesnt match the current
// records id, copy it to the temp directory
if(people.phone != Temp.phone)
{
// Write the record to copy.dat
copy.write(reinterpret_cast<char*>(&people),sizeof(Info));
}
// Read the next line from customer.dat
erase.read(reinterpret_cast<char*>(&people),sizeof(Info));
}
// Close both files
erase.close();
copy.close();
}
// Delete the Old customer.dat file
remove("stuff.dat");
// Rename the temporary holder to "customer.dat"
rename("stuff2.dat","stuff.dat");
}
You're taking an improperly formatted double (inputted from the cin >> recNum), seeking that far (*sizeof(people) into the file, and going from there. Seems like you need to start there.
Looks like you are entering the phone number in recNum (in the format 201.123.1111) and doing a seekg, which will give incorrect results