reading bytes using fstream c++ - c++

I created a read / write of bytes into a binary file using fstream object
#include <iostream>
#include <fstream>
using namespace std;
#define COL_WIDTH 20
int writeBinaryFile(char *desPath);
int readBinaryFile(char *desPath);
int age;
char name[COL_WIDTH];
int recsize = sizeof(int)+sizeof(name);
int n;
int main(){
char desPath[MAX_PATH+1];
char input[2];
while(true){
cout << "Main Menu:\n1 Write Binary File\n2 Read Binary File\n3 EXIT" << endl;
cin.getline(input, 2);
if(atoi(input)== 1){
cout << "Enter destination path:" << endl;
cin.getline(desPath, MAX_PATH+1);
for(;;){
int output = writeBinaryFile(desPath);
if(output == 1) break;
else if(output == 2) { *input = '4'; break;}
}
}
else if(atoi(input) == 2){
cout << "Enter destination path:" << endl;
cin.getline(desPath, MAX_PATH+1);
for(;;){
int output = readBinaryFile(desPath);
if(output == 1) break;
else if(output == 2){ *input = '4'; break;}
}
}
else if(atoi(input) == 3)
break;
else cout << "You entered wrong input, enter only 1 or 2." << endl;
if(atoi(input) == 4) continue;
else break;
}
system("pause");
return 0;
}
int writeBinaryFile(char *desPath){
char option[2];
fstream wBin(desPath, ios::binary | ios::out);
if(!wBin){
cout << desPath << " is not good path."<< endl;
return 1;
}
cout << "Enter name: " << endl;
cin.getline(name,COL_WIDTH);
cout << "Enter age: " << endl;
cin >> age;
cout << "Enter record number: " << endl;
cin >> n;
wBin.seekp(n*recsize);
wBin.write(name, sizeof(name));
wBin.write((char*)&age, sizeof(age));
wBin.close();
cout << "Enter record again? Press:" << endl
<< "Enter to continue" << endl
<< "Q to quit" << endl
<< "M to go back to main menu" << endl;
cin.ignore(256,'\n');
cin.getline(option,2);
if(option[0] == 'q' ||option[0] == 'Q') return 1;
else if(option[0] == 'm' ||option[0] == 'M') return 2;
return 0;
}
int readBinaryFile(char *desPath){
char option[2];
fstream rBin(desPath, ios:: binary | ios:: in);
if(! rBin){
cout << "File not found!" << endl;
return 1;
}
cout << "What record number?" <<endl;
cin >> n;
rBin.seekp((n*recsize));
rBin.read(name,sizeof(name));
rBin.read((char*)&age, sizeof(int));
cout << name <<endl;
cout << age << endl;
rBin.close();
cout << "Print more? Press enter. Press Q to QUIT or M to go back." << endl;
cin.clear();
cin.sync();
cin.getline(option, 2);
if(option[0] == 'q'|| option[0] == 'Q'){rBin.close(); return 1;}
else if(option[0] == 'm' || option[0] == 'M'){rBin.close(); return 2;}
return 0;
}
i created a binary file first with name, age, recordnumber ( position of bytes which is 0) then on second loop i input name, age, recordnumber 2.
When i tried to read the first pair(char*, int) of bytes pos(0) but it returns wrong result but when i tried to read the last pair in pos(1) it returns correct result.
I also tried making 3 times the input, but only the last char* and int is correct.
Why is it getting wrong results in first bytes(name(20bytes),age(4bytes)) but getting correct it last bytes?

In each call to writeBinaryFile the output is reopened, destroying the previous contents of the file.
You'll want to use ios::binary | ios::ate | ios::out | ios::in.
But, this bitmask will not create the file if it does not exist. You can work around that problem with this code sequence:
int writeBinaryFile(char *desPath) {
...
// Create the file only if it doesn't exist
fstream(desPath, ios::binary|ios::out|ios::app);
// Now it exists -- open it
fstream wBin(desPath, ios::binary|ios::out|ios::in);
...
}
Credit #JoeFish for the useful part of the answer.

Related

output within compiler and from exe file differs

i am using turbo c++. when i run the following code from compiler i get different answer at marked point in function result(int) then what i get from running .exe file created.
#include<fstream.h>
#include<conio.h>
#include<process.h>
#include<iomanip.h>
#include<string.h>
#include<stdio.h>
#include<dos.h>
ifstream fil;
int pos[50];
char date[11];
void exitt(int times = 0)
{
cout << endl << endl << " Enter 0 to exit." << endl;
if (times == 0)
cout << " Enter L to return to last screen." << endl;
}
void options();
void companychoose();
void companyscreen(int);
void write(int ch, int pos = 0) //add a check for duplicacy
{
ofstream fout;
clrscr();
if (ch == 1)
{
fout.open("database.dat", ios::binary | ios::app | ios::ate);
char companyname[20], temp;
exitt();
cout << " Enter Company name: ";
gets(companyname);
if (strcmp(companyname, "0") == 0)
exit(0);
else if (strcmp(companyname, "l") == 0)
options();
for (int i = 19; i>0; i--)
companyname[i] = companyname[i - 1];
companyname[0] = '%';
fout << endl;
fout << companyname;
fout.close();
cout << " Add data now?(y/n)" << endl;
askagain:
cin >> temp;
switch (temp)
{
case 'y':
fil.close();
write(2);
break;
case 'n':
options();
break;
default:
cout << " Invalid input" << endl;
goto askagain;
break;
}
}
}
void result(int ch)
{
int high[4], low[4], end, i = 0, enough = 0, temp = 0;
char check[20];
fil.open("database.dat", ios::binary);
fil.seekg(pos[ch], ios::beg);
fil >> check;
cout << endl;
if (check[0] == '%')
{
cout << " Not Enough Data!!!" << endl;
fil.close();
return;
}
while (!fil.eof())
{
if (i == 3)
{
i = 0;
enough = 1;
}
fil >> high[i] >> low[i] >> end >> check;
if (check[0] == '%')
break;
i++;
}
low[i] = 0;
temp = low[0];
if (enough == 0)
cout << " Not Enough Data!!!" << endl;
else
{
for (i = 0; i<3; i++)
{
if (low[i]<low[i + 1])
temp = low[i + 1];
}
if (temp>end)
cout << " Stock Running Low!!";
else if (temp = end)
cout << " Stock Is Stable";
else
cout << " Stock is HIGH!!";
cout << " " << end - temp << endl << endl << endl;
}
fil.close();
}
int read(int ch, int find = 0)
{
clrscr();
result(ch);
fil.open("database.dat", ios::binary);
fil.seekg(pos[ch], ios::beg);
char entry[20];
fil >> entry;
cout << setw(20) << "Date" << setw(10) << "High" << setw(10) << "Low" << setw(10) << "Close" << endl;
while (entry[0] != '%')
{
if (find == 1)
{
if (strcmp(entry, date))
return(fil.tellg() - 11);
else
continue;
}
cout << setw(20) << entry;
fil >> entry;
cout << setw(10) << entry;
fil >> entry;
cout << setw(10) << entry;
fil >> entry;
cout << setw(10) << entry << endl;
fil >> entry;
delay(500);
}
fil.close();
getch();
clrscr();
companyscreen(ch);
}
void edit(int ch)
{
cout << "Enter date of data to be edited";
gets(date);
write(2, read(ch, 1));
}
void companyscreen(int ch)
{
int ch1;
askagain:
result(ch);
cout << " 1. Add Data" << endl;
cout << " 2. Show history" << endl;
cout << " 3. Edit Data" << endl;
exitt();
ch1 = getch() - 48;
if (ch1 == 1)
write(2);
else if (ch1 == 2)
read(ch);
else if (ch1 == 3)
{
read(ch);
edit(ch);
}
else if (ch1 == 0)
{
cout << " exiting!!" << endl;
exit(500);
}
else if (ch1 == 60)
companychoose();
else
{
cout << " Invalid option chosen" << endl;
getch();
clrscr();
goto askagain;
}
}
void companychoose()
{
char name[20];
int i, ch;
clrscr();
fil.open("database.dat", ios::binary);
askagain:
fil.seekg(0, ios::beg);
cout << " Choose Company:";
cout << endl;
i = 1;
while (!fil.eof())
{
fil >> name;
if (name[0] == '%')
{
name[0] = ' ';
pos[i] = fil.tellg();
cout << setw(10) << i << "." << name << endl;
i++;
}
}
fil.close();
exitt();
ch = getch() - 48;
if (ch == 0)
exit(0);
else if (ch == 60)
options();
else if (ch>i)
{
cout << "Invalid choice" << endl;
getch();
clrscr();
goto askagain;
}
clrscr();
companyscreen(ch);
}
void options()
{
int ch;
clrscr();
askagain:
cout << endl << endl;
cout << " 1. Add company" << endl;
cout << " 2. Choose company" << endl;
exitt(1);
ch = getch() - 48;
if (ch == 1)
write(1);
else if (ch == 2)
companychoose();
else if (ch == 0)
{
cout << setw(10) << " Exiting!!";
exit(500);
}
else
{
cout << setw(10) << " Invalid choice chosen" << endl;
getch();
clrscr();
goto askagain;
}
}
void main()
{
clrscr();
textbackground(MAGENTA);
textcolor(WHITE);
clrscr();
options();
getch();
}
pls note that program is yet not fully complete so some features dont work.
i don't know how to include dat file data nor screenshot here.
i don't use visual c++ cause my pc is slow.
i don't use codeblocks cause i dont know how to use it. above code give hundreds of error even after adding "using namespace std;"
pls help me solve it. if you need anything else then ask me. thanks
I get different answer (…) in function result(int) then what I get from running .exe file created.
When you execute your program from the IDE a different working directory is used so different files are seemingly present/missing. Usually the working directory is configurable.
By the way, the goto is not needed. Really, it is not.

How to rename a file in C++

The part of code where I rename the file just won't work. I tried writing it separately in another project, it works. Help me please.
#include <iostream>
#include <stdio.h>
#include <fstream>
using namespace std;
int main () {
char address[] = "";
char newname[] = "";
int action;
char confirm;
int result;
cout << "File Manipulator 1.0" << endl;
cout << "--------------------" << endl << endl;
cout << "Type the full address of a file you wish to manipulate." << endl << endl;
ADDRESS:cin >> address;
fstream file(address);
if (!file.good()) {
cout << "The selected file does not exist! Try again. ";
goto ADDRESS;
} else {
cout << endl << "-----------------------------------" << endl;
cout << "Type 1 to move the selected file." << endl;
cout << "Type 2 to rename the selected file." << endl;
cout << "Type 3 to delete the selected file." << endl;
cout << "-----------------------------------" << endl << endl;
ACTION:cin >> action;
if (action == 1) {
cout << 1;
} else if (action == 2) {
cout << "Enter the new name: ";
cin >> newname;
cout << "Are you sure you want to rename the selected file? Y/N ";
CONFIRM:cin >> confirm;
if (confirm == 'Y' || 'y') {
result = rename(address, newname);
if (result == 0) {
cout << "renamed";
} else {
perror("not renamed");
}
} else if (confirm == 'N' || 'n') {
cout << "No";
} else {
cout << "You typed an invalid command! Try again. ";
goto CONFIRM;
}
} else if (action == 3) {
cout << 3;
} else {
cout << "You typed an invalid command! Try again." << endl;
goto ACTION;
}
}
return 0;
}
BTW the whole code is not finished, so check just the renaming part. Thanks.
Well, this is the solution.
#include <iostream>
#include <cstdio>
#include <fstream>
#include <string>
using namespace std;
int main() {
string address;
string newname;
Here you can see I used strings instead of char arrays.
char input;
int action;
char confirm;
int result;
cout << "File Manipulator 1.0" << endl;
cout << "--------------------" << endl << endl;
cout << "Type the full address of a file you wish to manipulate." << endl << endl;
getline(cin, address);
ifstream myfile(address.c_str());
I used ifstream with c_str() function which passes contents of a std::string into a C style string.
// try to open the file
if (myfile.is_open())
{
When the condition is met, you must close the opened file in order to be able to manipulate/work with it later.
myfile.close();
CREATE:cout << endl << "-----------------------------------" << endl;
cout << "Type 1 to move the selected file." << endl;
cout << "Type 2 to rename the selected file." << endl;
cout << "Type 3 to delete the selected file." << endl;
cout << "-----------------------------------" << endl << endl;
cin >> action;
switch (action)
{
case 1:
{
// do nothing.
}
break;
case 2:
{
// rename file.
cout << "Enter the new name" << endl << endl;
cin.ignore();
I used here the ignore() function to ignores the amount of characters I specify when I call it.
getline(cin, newname);
cout << "Are you sure you want ot rename the selected file ? Y/N" << endl << endl;
cin >> confirm;
if (confirm == 'Y' || confirm == 'y')
{
Same case with c_str() that i explained earlier.
rename(address.c_str(), newname.c_str());
}
}
break;
case 3:
{
// delete file.
remove(address.c_str());
}
break;
default:
{
cout << "You typed an invalid command!" << endl;
}
break;
}
}
else
{
cout << "The selected file does not exist! Would you like to create it? ";
cin >> input;
If the file name you input doesn't exist, you are prompted to create a file with the specified name, then you are redirected with goto to the manipulation menu.
if (input == 'y' || input == 'Y')
{
// create the file.
ofstream output(address.c_str());
output.close();
cout << "File created";
goto CREATE;
}
}
return 0;
}
Thanks for trying anyway :)

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.";
}
}

Saving c++ array of struct to file and issue for adding new elements to it

There are two main problems with my program that I am currently having. The first is I am unable to add more than one account to my program while it is running (I need to close it and re-open before I can add another). The second issue is when I don't add any accounts to my program addresses get saved to the program, this is what the file looks like when I don't add any accounts to the program.
123#John Smith#0#0###-1.07374e+008#-1.07374e+008#
The first part of the file is correct, but the addresses are coming from somewhere else in memory. This is what my code looks like.
#include <iostream>
#include <iomanip>
#include <string>
#include <cmath>
#include <fstream>
#include <sstream>
using namespace std;
struct account
{
string acctNum;
string name;
float cBal;
float sBal;
};
int menu();
char subMenu();
int loadCustomers(account[]);
void saveCusomers(account[], int);
int newCustomer(account[], int);
int deleteCustomer(account[], int);
int findCustomer(account[], int);
void deposit(account[], int);
void withdrawl(account[], int);
void balance(account[], int);
void bankBalance(account[], int);
int main()
{
account acc[20];
int selection;
int numAcc = 0;
int search;
numAcc = loadCustomers(acc);
do
{
selection = menu();
if(selection == 1)
{
newCustomer(acc, numAcc);
}
else if(selection == 2)
{
deleteCustomer(acc, numAcc);
}
else if(selection == 3)
{
search = findCustomer(acc, numAcc);
if (search == -1)
{
cout << "That account doesn't exist." << endl;
system("pause");
system("cls");
}
else
{
cout << right << setw(3) << acc[search].acctNum << "" << left << setw(15) << acc[search].name << acc[search].cBal << acc[search].sBal << endl;
system("pause");
system("cls");
}
}
else if(selection == 4)
{
deposit(acc, numAcc);
}
else if(selection == 5)
{
withdrawl(acc, numAcc);
}
else if(selection == 6)
{
balance(acc, numAcc);
}
else if(selection == 7)
{
bankBalance(acc, numAcc);
}
else if(selection == 8)
{
break;
}
} while (selection != 8);
saveCusomers(acc, numAcc);
return 0;
}
int menu()
{
int select;
cout << "Main Menu" << endl;
cout << "=============" << endl;
cout << "1. New Account" << endl;
cout << "2. Delete Account" << endl;
cout << "3. Find Customer" << endl;
cout << "4. Deposit" << endl;
cout << "5. Withdrawl" << endl;
cout << "6. Balance" << endl;
cout << "7. Bank Balance" << endl;
cout << "8. Exit" << endl;
cout << "=============" << endl;
cout << "Enter choice: ";
cin >> select;
while (select < 1 || select > 8)
{
cout << "Invalid input, select a number between 1 and 8: ";
cin >> select;
}
system("cls");
return select;
}
char subMenu()
{
char choice;
cout << "Which account? <C>hecking or <S>aving: ";
cin >> choice;
while(choice != 'C' && choice != 'c' && choice != 'S' && choice != 's')
{
cout << "Invalid choice, choose either checking or saving: ";
cin >> choice;
}
return choice;
}
int loadCustomers(account acc[])
{
ifstream inFile;
int numCustomers = 0, i = 0;
string ctemp, stemp;
inFile.open("customer.dat");
if (!inFile)
{
cout << "No customer file found." << endl;
}
else
{
cout << "Customer file found..." << endl << endl;
while (getline(inFile, acc[i].acctNum, '#'))
{
getline(inFile, acc[i].name, '#');
getline(inFile, ctemp, '#');
getline(inFile, stemp, '#');
istringstream(ctemp) >> acc[i].cBal;
istringstream(stemp) >> acc[i].sBal;
i++;
numCustomers++;
}
cout << "Number of customers found in file: " << numCustomers << endl;
}
system("pause");
system("cls");
inFile.close();
return numCustomers;
}
void saveCusomers(account acc[], int numCustomers)
{
ofstream outFile;
outFile.open("customer.dat");
for (int i = 0; i < numCustomers; i++)
{
outFile << acc[i].acctNum;
outFile << '#';
outFile << acc[i].name;
outFile << '#';
outFile << acc[i].cBal;
outFile << '#';
outFile << acc[i].sBal;
outFile << '#';
}
outFile << acc[numCustomers].acctNum;
outFile << '#';
outFile << acc[numCustomers].name;
outFile << '#';
outFile << acc[numCustomers].cBal;
outFile << '#';
outFile << acc[numCustomers].sBal;
outFile << '#';
cout << numCustomers + 1 << " accounts saved into the file." << endl;
outFile.close();
}
int newCustomer(account acc[], int numCustomers)
{
cout << "New Customer" << endl;
cout << "============" << endl;
cout << "Enter account number: ";
cin >> acc[numCustomers].acctNum;
cout << "Enter name: ";
cin.ignore();
getline(cin, acc[numCustomers].name);
acc[numCustomers].cBal = 0;
acc[numCustomers].sBal = 0;
numCustomers++;
return numCustomers;
}
int deleteCustomer(account[], int)
{
return 0;
}
int findCustomer(account acc[], int numCustomers)
{
string target;
cout << "Enter the account number you are looking for: ";
cin >> target;
for (int i = 0; i < numCustomers; i++)
{
if (acc[i].acctNum == target)
{
return i;
}
}
return -1;
}
How can I change this to make it so I can add more than one account when the program is running, and how can I make it so the program won't save an address to my file when nothing is added? I would also like to know why those addresses are being saved like that.
In main() you loadCustomers() in acc[] and you keep a record of the number of customers in local variable numAcc. At the end of main() you saveCustomers() the numAcc in acc[].
1. Your saving function is wrong:
in your loop for (int i = 0; i < numCustomers; i++) { ...}, you first write each customer from 0 to numAcc-1. This is correct.
But afterwards you write again an additional account, with the offset of numAcc. So you're writng one more account than you have. And the values of this account are not initialized, which explains the weird numbers you see.
You do this even if no account was added. And you know that you are doing it, because you've written cout << numCustomers + 1 << " accounts saved into the file."
Correction: just save the accounts you have, in the loop.
2.Your adding function is correct but you don't use it as you've planned:
When you add a customer with newCustomer() your function increments its local variable so that it knows that there is one more customer. Your function correctly returns this new number.
Unfortunately, in main() you do nothing with this returned value, so that numAcc remains unchanged.
Correction: Correct the following statement in main():
if (selection == 1)
{
numAcc = newCustomer(acc, numAcc); // update the number of accounts
}
3. Miscellaneous remarks:
You don't check in newCustomers() if your acc[] array is already full. If you add a 21st account, it'll be a segfault !
The same applies to load. You cannot be sure that nobody added a line to the file with a text editor. So there is as well a risk of reading more lines that there is space in your arry.
Nothing happens in deleteCustomer() I suppose you haven't written it yet. Think that this function could change the number of accounts, exactly as newCustomer().
As most banks have more than twenty customers, I assume that it's an exercise for school. I don't know if you're allowed to do so, but I'd highly recommend to replace arrays with vectors.

Losing Data while Writing and Reading Data from File (Random Access File, C++)

Firstly, I initialize the "hardware.dat" file by writing the following data and then display them in list form.
However, when I process choice 2 and then exit choice 2 without editing or adding anything, all the data lose. I propose that anything will not be changed.
Why the problem exist? How to fix it?
Thank you for your attention.
Code :
int question_3()
{
cout << "Question 3" << endl;
create_One_Hundred_blank_Data();
char choice = '0';
do
{
cout << "---------------Main Menu---------------" << endl
<< "1. Initialize hardware data." << endl
<< "2. Add / Edit data." << endl
<< "3. Remove data." << endl
<< "4. Show whole data in the file." << endl;
cout << "Enter choice > "; choice = getch(); cout << choice << endl; // #include <conio.h>
switch_Choice(choice);
}while (choice != '0');
cout << "Program is ended." << endl;
return 0;
}
void switch_Choice(char choice)
{
switch (choice)
{
case '1':
choice_1();
break;
case '2':
choice_2();
break;
case '3':
choice_3();
break;
case '4':
choice_4();
break;
}
}
void choice_2()
{
hardware.open("hardware.dat", ios::binary | ios::out);
if (!hardware)
{
cerr << "File could not be opened." << endl;
exit(1);
}
int record = 0;
string tool_name = "";
int quantity = 0;
int cost = 0;
string buffer_Eater = "";
cout << "Enter record number <O to exit input> : "; cin >> record;
while(record != 0)
{
cout << "Enter tool name : "; getline(cin, tool_name); getline(cin, buffer_Eater);
cout << "Enter quantity : "; cin >> quantity;
cout << "Enter cost : "; cin >> cost;
write_Single_Data(myHardwareData, record, tool_name, quantity, cost);
cout << "Enter record number <O to exit input> : "; cin >> record;
}
hardware.close();
output_Whole_File_Data();
separation_line();
}
void output_Whole_File_Data()
{
hardware.open("hardware.dat", ios::binary | ios::in);
output_Data_LineHead();
hardware.read(reinterpret_cast<char *>(&myHardwareData), sizeof(HardwareData));
int counter = 0;
cout << setprecision(2) << fixed;
while (hardware && !hardware.eof())
{
if (myHardwareData.getRecord() != 0)
output_Data_Line(cout, myHardwareData);
hardware.read(reinterpret_cast<char *>(&myHardwareData), sizeof(HardwareData));
}
hardware.close();
}
Try to replace
hardware.open("hardware.dat", ios::binary | ios::out);
by
hardware.open("hardware.dat", ios::binary | ios::out | ios::app);