How would I append data to this file - c++

Hello I am creating a program that has the user enter a ssn based on a text file and then it reports that information and calculates the mean of a grade.
I am struggling to understand how I can allow the user to directly add data to the text file based on a series of questions.
The text file uses this format.
111-11-1111
John Doe
G
85 90 87 95 89
111-11-1112
Jane Doe
P
78 65 71 74 75
111-11-1113
John Smith
G
45.0 43.0 44.0 45.0 43.0
#include<iostream>
#include<iomanip>
#include<string>
#include<fstream>
using namespace std;
int main() {
int selection = 0;
char goagain;
bool again = true;
ifstream fin;
ofstream fout;
string SSNFind, SSN, name, attendance, trash;
int Lab, PA, Quiz, Midterm, Final;
;
cout << "********** GRADE SYSTEM ************" << endl << endl;
while (again) {
while (selection > 4 || selection < 1)
{
cout << setw(30) << left << "1. Add a record" << endl;
cout << setw(30) << left << "2. Find a person by SSN" << endl;
cout << setw(30) << left << "3. Display all records" << endl;
cout << setw(30) << left << "4. Exit " << endl;
cout << "MAKE A CHOICE" << endl;
cin >> selection;
}
switch (selection)
{
case 1:
break;
case 2:
fin.open("data.txt", ios::in);
//check
cout << "what SSN do you want to find? ";
cin >> SSNFind;
getline(fin, SSN);
while (!fin.eof())
{
getline(fin, name);
getline(fin, attendance);
fin >> Lab >> PA >> Quiz >> Midterm >> Final;
getline(fin, trash);
if (SSN == SSNFind)
{
cout << left << setw(12) << SSN << setw(25) << name << setw(3) << attendance << Final;
}
getline(fin, SSN);
}
fin.close();
break;
case 3:
cout << "Display" << endl;
break;
default:
cout << "exit";
exit(1);
break;
}
cout << "again?(Y or N)";
cin >> goagain;
if (toupper(goagain) == 'Y')
{
again = true;
selection = 0;
}
else
{
again = false;
exit(1);
}
}
}

I'm not 100% sure I understand your problem, but if you want to append data to a file, you should open in in "append" mode, instead of "in"/"out" mode:
fin.open("data.txt", ios::in);
to:
fin.open("data.txt", std::ios::app);
see details:
https://en.cppreference.com/w/cpp/io/basic_fstream/open

I wanted to post this as a comment because I'm not sure if this is really an answer.
If you want to append to the end of the file you would open the file in append mode as suggested by Thomas Matthews above.
If you want to insert into the middle or beginning of the file you could open the file in input/output mode and find where you want to insert data at. Then you would buffer from there to the end of the file, return to where you want to insert into file and then write what you need to add then write the buffer back into file. (input/output mode overwrites data in file). If the file is large you should buffer only a portion of the file at a time, two buffers may help here.
Reading from here and looking at the other stream based classes to the left of linked page; I see no way to directly insert into the middle of file without buffering.

Related

How to ignore .txt for cin for output file in C++?

This is my C++ code and I wish to create an output file. In order to create the output file, I request the user to include .txt at this input, cin >> accnum ; , hence, when output file is produced, it will show accnum.txt as plain text. My question is, what should I do in order to ignore .txt to be appeared in the text file, provided that I must input .txt(this is to produce txt file, without .txt at the input, no output file will be produced). I have put a comment line, kindly refer to that line. Thanks for your help!
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
int main ()
{
double withdraw,deposit,number,transfer,num,amt;
string name,first_name,middle_name,last_name;
int x=0;
int option;
int A = 300;
int B = 500;
int C,W,y;
string accnum;
ifstream infile;
ofstream outfile;
do {
cout <<" Welcome to ATM Machine "<<endl;
cout <<"\n\t****Menu****";
cout <<"\n\t* 1.Creating a new account *";
cout <<"\n\t* 2.Cash Deposit *";
cout <<"\n\t* 3.Cash withdrawal *";
cout <<"\n\t* 4.Fund transfer between two account *";
cout <<"\n\t* 5.Exit *";
cout <<"\n\t* *";
cout <<"\n\t********";
cout <<"\n\t Please choose an option: ";
cin>>option;
switch(option){
case 1:
cout <<"Press 1 to Confirm" << endl << "Press 0 to exit " << endl ;
cin >> C ;
{
if( C == 1 )
{
cout << "Enter first name: " << endl;
cin >> first_name;
cout << "Enter middle name: " << endl;
cin >> middle_name;
cout << "Enter last name: " << endl;
cin >> last_name;
name = first_name + " " + middle_name + " " + last_name;
cout << "enter a 4 digit number : " << endl << "gentle reminder : please add .txt at the end of your number" << endl << "e.g 1234.txt" << endl;
cin >> accnum ; //how to ignore .txt
cout << "What is your primary balance: " << endl;
cin >> amt;
infile.open(name);
outfile.open(name);
cout << "your account has been created " << endl ;
outfile << "name" << name << endl;
outfile << "account no. : " << accnum << endl ;
outfile << "current balance : RM" << amt << endl ;
}else {
cout << "Bye, have a nice day";
}
infile.close();
outfile.close();
}
break;
case 2:
cout<<"Deposit amount: "<<endl;
cin>>deposit;
if(deposit<10) {
cout<<"The smallest note acceptable is RM10."<<endl;
}else {
x=static_cast<int>(deposit)%10;
if(x!=0)
{
cout<<"Invalid deposit amount"<<endl;
cout<<"Example of deposit amount: RM10, RM20, RM50, RM320..."<<endl;
}else {
A+=deposit;
cout<<"current balance: RM"<< A <<endl;
}
}
break;
case 3:
cout<<"Amount you want to withdraw"<<endl;
cin>>withdraw;
if(A < withdraw || withdraw < 10) { // A is balance
cout <<"Failed to withdraw money! Please try again."<<endl;
}else {
A-=withdraw;
cout <<"current balance: "<< A <<endl;
}
break;
case 4:
infile.open("1212.txt");
infile >> x;
cout<<"Enter Details of transfering Account(Account A)"<<endl;
cout<< "Your account number is:"<<endl;
cin>>W;
cout<< "What is your name:"<<endl;
cin.ignore();
getline(cin,name);
cout<<"Enter Details of receiving Account(Account B)"<<endl;
cout<<"Enter account number:"<<endl;
cin>>W;
cout<<"Enter name:"<<endl;
cin.ignore();
getline(cin, name);
cout <<"your account balance is : " << x << endl << "how much do you want to transfer ? ";
cin >> num ;
outfile.open("1212.txt");
outfile << x - num ;
cout << "your account balance is : " << x - num ;
infile.close();
outfile.close();
infile.open("2121.txt");
infile >> y ;
outfile.open("2121.txt") ;
outfile << y + num ;
infile.close();
outfile.close();
break;
case 5:
cout<<"Thank you for using ATM machine. Bye, have a nice day !"<<endl;
return 0;
default:
if(option != 5) cout<<"Invalid option.Please try again!"<<endl;
break;
}
}while(option != 5);
system("pause");
return 0;
}
Just create the file without a format, the name will be the file_name content exactly, be aware that in windows has reserved names such as CON.
#include <iostream>
#include <fstream>
#include <string>
int main (void) {
std::string file_name = "1234";
std::fstream f_handle;
f_handle.open(file_name, std::fstream::out);
if (f_handle.is_open()){
f_handle << "Some text" << std::endl;
f_handle.close();
}
f_handle.open(file_name, std::fstream::in);
if (f_handle.is_open()){
std::cout << f_handle.rdbuf() << std::endl;
f_handle.close();
}
return 0;
}
You asked about how to remove the .txt part from accnum and here's one way to do that:
cin >> accnum ; //how to ignore .txt
// check that the length/size of the entered accnum is at least 4 characters
// and
// that the last 4 characters is ".txt"
if(accnum.size() >= 4 && accnum.substr(accnum.size() - 4) == ".txt") {
// extract a substring from accnum without the last 4 characters
accnum = accnum.substr(0, accnum.size() - 4);
}
However, I have my doubts about the requirement that the user should actually add .txt to the account number, because seeing this at an ATM would be really confusing:
enter a 4 digit number :
gentle reminder : please add .txt at the end of your number"
e.g 1234.txt
It's especially confusing since the only thing you want to do with .txt is to remove it. I would consider changing this user interface.
Suggestions:
Let the user add the account number without .txt
Instead of saving the account information in a file with the account holders name as the filename, save it in a file named accnum + ".txt". This makes it possible for a person to have more than one account - just as in real life.

get line function in c++ not working as it should

I was trying to get the user input and it should include a space because I am asking for a full name. So I used the getline method but I can't input the data correctly.
Here's the code:
#include <iostream>
#include <string>
string name, mobile, landline, work;
cout << "Enter the name of the contact to be added:";
getline(cin, name);
cout << "Enter the mobile number of this contact:";
getline(cin, mobile);
cout << "Enter the landline number of this contact:";
getline(cin, landline);
cout << "Enter the work number of this contact:";
getline(cin, work);
When I run the program this is what I get:
Enter the name of the contact to be added:Enter the mobile number of this contact:
This is the main method:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/*
* File: main.cpp
* Author: Gaby
*
* Created on March 25, 2020, 7:14 PM
*/
#include "Contact.h"
#include "DCSList.h"
#include <iomanip>
#include <fstream>
#include <sstream>
using namespace std;
void showMenu();
void saveChanges(ofstream& file, DCSList& list);
/*
*
*/
int main(int argc, char** argv) {
fstream file; //This is the file we read from
ofstream outputFile; //This is the file we will write on at the end
string name, numberString; //Strings to extract the data from the file
string numbers[3]; //string array of numbers
string numberExtracted; //Used to extract each number from the numberString
string numbOfContacts; //Number of Contacts we want to read from file
int number; //Integer variable of the parsed value of the number read
int counter = 1; //Number of contacts read from file
int choice = 0; //Choice of user
DCSList list;
file.open("./ContactList.txt");
if(file.is_open()){
//If file is open then read from it
//First get the number of contacts in list
getline(file, numbOfContacts);
//Convert the number in the file to an integer
stringstream count(numbOfContacts);
//Set the value of number
count >> number;
while(counter <= number){
//Extract the name of the contact
getline(file, name);
//Extract the mobile, work and home numbers
getline(file, numberString);
//We will need to split the numberString with the - as delimiter
stringstream ss(numberString);
int i = 0; //Counter for numbers
while(getline(ss, numberExtracted, '-')){
numbers[i] = numberExtracted;
i++;
}
//Create a Contact object and add the contact to the list
Contact c(name, numbers[0], numbers[1], numbers[2]);
list.addNode(c);
counter++;
}
//Write on the other file
outputFile.open("NewContactList.txt");
if (outputFile.is_open()){
list.start();
while(list.hasNext()){
outputFile << list;
list.operator ++();
}
}
else{
cout << "File not opened!" << endl;
}
outputFile.close();
}
else{
cout << "File is not opened!" << endl;
}
file.close();
do{
showMenu();
cin >> choice;
switch(choice){
case 1:{
list.start();
while(list.hasNext()){
cout << list;
list.operator ++();
}
break;
}
case 2:
{
string name, mobile, landline, work;
cout << "Enter the name of the contact to be added:";
getline(cin, name);
cout << "Enter the mobile number of this contact:";
getline(cin, mobile);
cout << "Enter the landline number of this contact:";
getline(cin, landline);
cout << "Enter the work number of this contact:";
getline(cin, work);
//Create a contact object
Contact contact(name, mobile, work, landline);
//Add contact to list
list.addNode(contact);
}
break;
case 3:
{
string contactToDelete;
cout << "Enter a contact name or "
"any mobile, work, land number :";
cin >> contactToDelete;
if (list.deleteNode(contactToDelete)){
cout << "Contact has been deleted!" << endl;
}
}
break;
case 4:
{
string searchCriteria;
cout << "Enter a contact name or "
"any mobile, work, land number :";
getline(cin, searchCriteria);
if (list.searchNode(searchCriteria)){
cout << list;
}
else{
cout << "No contact found!" << endl;
}
break;
}
case 5:
{
cout << "Thank you for using the program." << endl;
cout << "All changes applied will be "
"saved to the output file" << endl;
//Write on the other file
outputFile.open("NewContactList.txt");
if (outputFile.is_open()) {
list.start();
while (list.hasNext()) {
outputFile << list;
list.operator++();
}
} else {
cout << "File not opened!" << endl;
}
file.close();
return 0;
}
default:{
cout << "Please enter a valid value to do an operation!" <<endl;
break;
}
}
}while(choice != 1 || choice != 2 ||
choice != 3 || choice != 4 || choice != 5);
return 0;
}
void showMenu(){
cout << "-------------PHONEBOOK-------------" << endl;
cout << "Enter a number according to "
"the operation you want to do: " << endl;
cout << "1. Show phone book" << endl;
cout << "2. Add new contact" << endl;
cout << "3. Delete a contact" << endl;
cout << "4. Search for a contact" << endl;
cout << "5. Exit program" << endl;
}
I am not able to input each value individually.
Do you know how can I fix this problem?
Thank you for your help.
How #NathanOliver has suspected you used a cin. In your main method in lines 111 and 153 (if formated in the same way as above) you can find them. Try to change them to getline() too. That should work.

Weird Text File Output and Writing Issues

In my code:
int newEntry()
{
string input;
Client person;
char response = 'y';
//create file object and open file
fstream customer("customer.dat", ios::out | ios::app);
if (!customer)
{
cout << "Error opening file. Program aborting." << endl;
return 0;
}
do
{
cout << "Enter person information:" << endl << endl;
cout << "Name: " << endl;
getline(cin, input);
strcpy(person.name, input.c_str());
cout << endl << "Street Adress (And Apartment Number):" << endl;
cin >> person.address1;
getline(cin, input);
strcpy(person.address1, input.c_str());
cout << endl << "City, State, Zipcode: " << endl;
cin >> person.address2;
getline(cin, input);
strcpy(person.address2, input.c_str());
cout << endl << "Phone: " << endl;
cin >> person.phone;
getline(cin, input);
strcpy(person.phone, input.c_str());
cout << endl << "Account Balance: " << endl;
cin >> person.acctBal;
//input validation to ensure a non neg number
cin.ignore();
cout << endl << "Last Payment: " << endl;
cin >> person.lastPay;
//input validation to ensure a non neg number
customer.write(reinterpret_cast<char *>(&person),
sizeof(person));
cout << endl << "Do you want to enter another record? (Enter Y for Yes, N
for No) " << endl;
cin >> response;
cout << "_______________________________________________" << endl << endl;
if (toupper(response) == 'Y')
{
cin.ignore();
}
} while (toupper(response) == 'Y');
customer.close();
return 1;
}
It seems as though the block:
cout << endl << "Street Address (And Apartment Number):" << endl;
cin >> person.address1;
getline(cin,input);
strcpy(person.address1, input.c_str());
and its neighboring address 2 prompt (identical) are causing bad output to the file when
customer.write(reinterpret_cast<char *>(&person),sizeof(person));
is used to write to the file. The output is missing the very first word . For example if "211 Harvey Road" was entered, 211 would be cut off. Another example, if "Harvey Road" was entered, than it seems as though "harvey" is cut off. When (in another function) the file is read, the structure of arrays is missing the beginning, as well as the file.
On top of that, in the textfile, this is the data being written to it:
Frank Palmasani ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ Harvey Road ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ Haven, Alabama ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ 504617772 ÌÌÌÌ èŽ# èŽ#James Harris ni ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ Street AVEN ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ China. Alabama ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ 546457474 ÌÌÌÌ ð? ð?
As you can see, where the Ì are popping up is where the file and program are somehow losing the first word. I have tried everything I can think of to fix this problem, hopefully someobody else has ran into a similar problem.
I have tried changing methods of saving the data held in the structure of arrays to the file, but found that I couldn't read from the file in one large grouping. In my text book, the method I used to read out to the file is used so that is the one I believe I should follow.
However, I am considering writing each one separately on each line, and saving it precisely in the order so that I can read it in the same order, saving it to a structure of vectors. Again, I'd I would like to avoid that but would love to hear your opinion on the matter whether if you are able to help me here or not.
In case you needed it, here is my structure:
const int NAME_SIZE = 51, ADDR_SIZE = 51, PHONE_SIZE = 14;
struct Client
{
char name[NAME_SIZE];
char address1[ADDR_SIZE];
char address2[ADDR_SIZE];
char phone[PHONE_SIZE];
double acctBal;
double lastPay;
};
Your output file looks like that because you are doing a raw dump of the Client struct. So there will be 51 bytes written for name, 51 for address1, etc. Regardless of string length.
You need to properly write each field individually.
customer << input.name << endl;
customer << input.address1 << endl;
etc.....
cout << endl << "Street Adress (And Apartment Number):" << endl;
cin >> person.address1;
getline(cin, input);
strcpy(person.address1, input.c_str());
You're getting the first token, in the case you mentioned 211 and putting it in address1, then getting the rest of the line and replacing what was in address1 with it. That's where your 211 went.
You should open the file in binary mode if your intent is to write/read entire structures as a binary blob like this. If you want to store the data as text use std::string, avoid the strcpy mess, and write/read each member individually on their own ines.

Why won't this piece of my code write to file

I am developing a C++ banking system.
I am able to get the float, newbal, values correctly and when I try to write to file, there is no data in the file.
else if (x == 2)
{
cout << "You have selected option number 2. Deposit.\n";
cout << "Please enter you account ID: ";
cin >> ID;
file.open("C:\\Users\\Raggulddon\\Desktop\\C++ supplement\\Cust_" + ID + ".dat", ios:: in | ios::out | ios::binary);
if (!file)
{
cout << "Sorry the requested account could not be located.\n";
}
else
{
file >> firstname >> lastname;
cout << endl << firstname << " " << lastname << endl;
cout << "-----------------------------------\n";
string line;
while (getline(file, line))
{
// stringstream the getline for line string in file
istringstream iss(line);
if (iss >> date >> amount)
{
cout << date << "\t\t$" << showpoint << fixed << setprecision(2) << amount << endl;
famount += amount;
}
}
cout << "Your balance is $" << famount << endl;
cout << "How much would you like to deposit today: $";
cin >> amountinput;
float newbal = 0;
newbal = (famount += amountinput);
cout << "\nYour new balance is: $" << newbal << ".\n";
file << date << "\t\t" << newbal; //***This should be writing to file
but it doesn 't.
file.close();
The text file looks like this:
Tony Gaddis
05/24/12 100
05/30/12 300
07/01/12 -300
// Console Output looks like this
Tony Gaddis
05/24/12 100
05/30/12 300
07/01/12 -300
Your balance is: #1
How much wuld you like to deposit: #2
Your new balance is: #1 + #2
write to file
close file.
// exits to main loop::::
How can I make it write to file and save it, and why is this happening.
I tried doing it with ostringstream as well considering how I used istringstream for the input. But it didn't work either:
float newbal=0;
newbal = (famount += amountinput);
ostringstream oss(newbal);
oss << date << "\t\t" << newbal;
I am trying to self teach C++ so any relevant information would be kindly appreciated.
If you want to write a text file, you should not use "ios::binary", when opening the file.

Unable to delete a record from a c binary program I created

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