目录:
- Creating a sequential file
- Reading and printing a sequential file
- credit inquiry program
- creating to a random-acces file
- writing to a random-access file
- reading from the random file
-
transaction-processing program
https://www.cplusplus.com/doc/tutorial/files/
1) Creating a sequential file
// Creating a sequential file
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
using namespace std;
int main() {
// ofstream outClientFile{"clients.txt", ios::out};
ofstream outClientFile{"clients.txt"}; // 默认是ios::out
if (!outClientFile) {
cerr << "File could not be opened" << endl;
exit(EXIT_FAILURE);
}
cout << "Enter the account, name, and balance.\n"
<< "Enter end-of-file to end input.\n";
int account;
string name;
double balance;
while (cin >> account >> name >> balance) {
outClientFile << account << ' ' << name << ' ' << balance << endl;
cout << "?";
}
}
/*
Enter the account, name, and balance.
Enter end-of-file to end input.
100 Jones 24.98
?200 Jone2 25
?^D
Process finished with exit code 0
*/
2)Reading and printing a sequential file
// Reading and printing a sequential file
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <cstdlib>
using namespace std;
void outputLine(int, const string&, double); // prototype
int main(){
ifstream inClientFile("clients.txt", ios::in);
if (!inClientFile) {
cerr << "File could not be opened" << endl;
exit(EXIT_FAILURE);
}
cout << left << setw(10) << "Account" << setw(13)
<< "Name" << "Balance\n" << fixed << showpoint;
int account;
string name;
double balance;
while (inClientFile >> account >> name >> balance) {
outputLine(account, name, balance);
}
}
void outputLine(int account, const string& name, double balance) {
cout << left << setw(10) << account << setw(13) << name
<< setw(10) << setprecision(2) << right << balance << endl;
}
3) credit inquiry program
// credit inquiry program
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <cstdlib>
using namespace std;
enum class RequestType{
ZERO_BALANCE = 1, CREDIT_BALANCE, DEBIT_BALANCE, END
};
RequestType getRequest();
bool shouldDisplay(RequestType, double);
void outputline(int, const string&, double);
RequestType getRequest(){
// display reques options
cout << "\nEnter request\n"
<< "1 - List accounts with zero balances\n"
<< "2 - List accounts with credit balances\n"
<< "3 - List accounts with debit balances\n"
<< "4 - End of run" << fixed << showpoint;
int type;
do { // input user request
cout << "\n?";
cin >> type;
}while (type < static_cast<int>(RequestType::ZERO_BALANCE) || type > static_cast<int>(RequestType::END));
return static_cast<RequestType>(type);
}
bool shouldDisplay(RequestType type, double balance) {
// determine whether to display zero balances
if (type == RequestType::ZERO_BALANCE && balance == 0) {
return true;
}
// determine whether to display credit balances
if (type == RequestType::CREDIT_BALANCE && balance < 0) {
return true;
}
// determine whether to display debit balances
if (type == RequestType::DEBIT_BALANCE && balance > 0) {
return true;
}
return false;
}
void outputLine(int account, const string& name, double balance) {
cout << left << setw(10) << account << setw(13) << name
<< setw(7) << setprecision(2) << right << balance << endl;
}
int main() {
// ifstream constructor opens the file
ifstream inClientFile{"clients.txt", ios::in};
if (!inClientFile) {
cerr << "File could not be opened" << endl;
exit(EXIT_FAILURE);
}
// get user's request
RequestType request{getRequest()};
// process user's request
while (request != RequestType::END) {
switch (request) {
case RequestType::ZERO_BALANCE:
cout << "\nAccounts with zero balances:\n";
break;
case RequestType::CREDIT_BALANCE:
cout << "\nAccounts with credit balances:\n";
break;
case RequestType::DEBIT_BALANCE:
cout << "\nAccounts with debit balances:\n";
break;
}
int account;
string name;
double balance;
// read account , name and blance from file
inClientFile >> account >> name >> balance;
while (!inClientFile.eof()) {
// display record
if (shouldDisplay(request, balance)) {
outputLine(account, name, balance);
}
inClientFile >> account >> name >> balance;
}
inClientFile.clear(); // reset eof for next input
inClientFile.seekg(0); // reposition to begining of file
request = getRequest(); // get additional request from user
}
cout << "End of run." << endl;
}
4) creating to a random-acces file
// ClientData.cpp
#include "ClientData.h"
#include <string>
using namespace std;
ClientData::ClientData(int accountNumberValue, const std::string& lastName, const std::string& firstName, double balanceValue):accountNumber(accountNumberValue), balance(balanceValue){
setLastName(lastName);
setFirstName(firstName);
}
// get account number value
int ClientData::getAccountNumber() const {return accountNumber;}
//set acc number
void ClientData::setAccountNumber(int accountNumberValue) {
accountNumber = accountNumberValue;
}
// get last name
string ClientData::getLastName() const {return lastName;}
// set last name
void ClientData::setLastName(const std::string& lastNameString){
size_t length{lastNameString.size()};
length = (length < 15 ? length : 14);
lastNameString.copy(lastName, length);
lastName[length] = '\0'; // append null charcter to lastName
}
// get first name
string ClientData::getFirstName() const {return firstName;}
// set first name
void ClientData::setFirstName(const std::string& firstNameString) {
size_t length{firstNameString.size()};
length = (length < 10 ? length : 9);
firstNameString.copy(firstName, length);
firstName[length] = '\0';
}
// get balance value
double ClientData::getBalance() const {return balance;}
// set balance
void ClientData::setBalance(double balanceValue) {
balance = balanceValue;
}
// ClientData.h
#ifndef PRACTICE_CLIENTDATA_H
#define PRACTICE_CLIENTDATA_H
#include <string>
class ClientData{
public:
ClientData(int=0, const std::string& = "", const std::string& = "", double = 0.0);
void setAccountNumber(int);
int getAccountNumber() const;
void setLastName(const std::string&);
std::string getLastName() const;
void setFirstName(const std::string&);
std::string getFirstName() const;
void setBalance(double);
double getBalance() const;
private:
int accountNumber;
char lastName[15];
char firstName[10];
double balance;
};
#endif //PRACTICE_CLIENTDATA_H
#include <iostream>
#include <fstream>
#include <cstdlib>
#include "ClientData.h"
// writing to a random-access file
using namespace std;
int main() {
ofstream outCredit{"credit.dat", ios::out | ios::binary};
if (!outCredit) {
cerr << "File could not be opend." << endl;
exit(EXIT_FAILURE);
}
ClientData blankClient; // constructor zeros out each data member
for (int i{0}; i < 100; ++i) {
outCredit.write(
reinterpret_cast<const char *>(&blankClient), sizeof(ClientData)
);
}
}
5) writing to a random-access file
// writing to a random-access file
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include "ClientData.h"
using namespace std;
int main() {
fstream outClient{"credit.dat", ios::in | ios::out | ios::binary};
if (!outClient) {
cerr << "Error happend when open file";
exit(EXIT_FAILURE);
}
int accountNumberValue;
string lastNameString;
string firstNameString;
double balanceValue;
cout << "Enter first accountNumberValue:" << endl;
cin >> accountNumberValue;
while (accountNumberValue > 0 && accountNumberValue < 100) {
cout << "Enter lastName, firstName, balance" << endl;
cin >> lastNameString;
cin >> firstNameString;
cin >> balanceValue;
ClientData client{accountNumberValue, lastNameString, firstNameString, balanceValue};
outClient.seekp((client.getAccountNumber() - 1) * sizeof(ClientData));
outClient.write(
reinterpret_cast<const char*>(&client), sizeof(ClientData)
);
cout << "Enter accountNumberValue again:" << endl;
cin >> accountNumberValue;
}
}
6) reading from the random file
// reading from the random file
#include <string>
#include <iostream>
#include <fstream>
#include <iomanip>
#include "ClientData.h"
using namespace std;
void outputline(ostream&, const ClientData&);
int main() {
ifstream inCrdit{"credit.dat", ios::in | ios::binary};
if (!inCrdit) {
cerr << "Open file failed" << endl;
exit(EXIT_FAILURE);
}
cout << left << setw(10) << "Account" << setw(16) << "Last Name"
<< setw(11) << "First Name" << setw(10) << right << "Balance\n";
ClientData client;
inCrdit.read(reinterpret_cast<char *> (&client), sizeof(ClientData));
while (inCrdit) {
if (client.getAccountNumber() != 0 ) {
outputline(cout, client);
}
inCrdit.read(reinterpret_cast<char*>(&client), sizeof(ClientData));
}
}
void outputline(ostream& output, const ClientData& record) {
output << left << setw(10) << record.getAccountNumber()
<< setw(16) <<record.getLastName()
<< setw(11) << record.getFirstName()
<< setw(10) << setprecision(2) << right << fixed << showpoint << record.getBalance() << endl;
}
7)transaction-processing program
//This program reads a random-access file sequentially, updates
//data previously written to the file, creates data to be placed
//in the file, and deletes data previously stored in the file.
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdlib>
#include "ClientData.h"
using namespace std;
enum class Choice {PRINT=1, UPDATE, NEW, DELETE, END}; // 会递增
Choice enterChoice();
void createTextFile(fstream&);
void updateRecord(fstream&);
void newRecord(fstream&);
void deleteRecord(fstream&);
void outputLine(ostream&, const ClientData&);
int getAccount(const char* const);
int main() {
fstream inOutCredit{"credit.dat", ios::in | ios::out | ios::binary};
if (!inOutCredit){
cerr << "File could not be opened." << endl;
exit(EXIT_FAILURE);
}
Choice choice;
while ((choice = enterChoice()) != Choice::END){
switch (choice) {
case Choice::PRINT:
createTextFile(inOutCredit);
break;
case Choice::UPDATE:
updateRecord(inOutCredit);
break;
case Choice::NEW:
newRecord(inOutCredit);
break;
case Choice::DELETE:
deleteRecord(inOutCredit);
break;
default:
cerr << "Incorrect choice" << endl;
break;
}
inOutCredit.clear();
}
}
Choice enterChoice(){
cout << "\nEnter your choice\n"
<< "1 - store a formatted text file of accounts\n"
<< " called\"print.txt\" for printing\n"
<< "2 - update an account \n"
<< "3 - add a new account\n"
<< "4 - delete an account\n"
<< "5 - end program\n?";
int menuChoice;
cin >> menuChoice;
return static_cast<Choice>(menuChoice);
}
// create formatted text file for printing
void createTextFile(fstream& readFromFile) {
ofstream outPrintFile("print.txt", ios::out);
if (!outPrintFile) {
cerr << "File could not be created." << endl;
exit(EXIT_FAILURE);
}
// output column heads
outPrintFile << left << setw(10) << "Account" << setw(16)
<< "Last Name" << setw(11) << "First Name" << right
<< setw(10) << "Balance" << endl;
readFromFile.seekg(0);
ClientData client;
readFromFile.read(
reinterpret_cast<char*>(&client), sizeof(ClientData)
);
while (!readFromFile.eof()) {
if (client.getAccountNumber() != 0) {
outputLine(outPrintFile, client);
}
readFromFile.read(
reinterpret_cast<char*>(&client), sizeof(ClientData)
);
}
}
// obtain account number value from user
int getAccount(const char* const prompt) {
int accountNumber;
do {
cout << prompt << "(1-100):";
cin >> accountNumber;
} while (accountNumber < 1 || accountNumber > 100);
return accountNumber;
}
// display
void outputLine(ostream& output, const ClientData& record){
output << left << setw(10) << record.getAccountNumber()
<< setw(16) << record.getLastName()
<< setw(11) << record.getFirstName()
<< setw(10) << setprecision(2) << right << fixed
<< showpoint << record.getBalance() << endl;
}
// update balance in record
void updateRecord(fstream& updateFile){
int accountNumber{getAccount("Enter account to update")};
updateFile.seekg((accountNumber - 1) * sizeof(ClientData)); // find pos
ClientData client; // create record obj, read first record from file
updateFile.read(reinterpret_cast<char*>(&client), sizeof(ClientData));
// update record
if (client.getAccountNumber() != 0) {
outputLine(cout , client); // display the record
cout << "\nEnter charge(-) or payment(-):";
double transaction; // charge or payment
cin >> transaction;
double oldBalance = client.getBalance();
client.setBalance(oldBalance + transaction);
outputLine(cout, client); // display
// find right file pos and wirte update record over old record
updateFile.seekp((accountNumber -1)*sizeof(ClientData));
updateFile.write(
reinterpret_cast<char*>(&client), sizeof(ClientData)
);
}
else {
cerr << "Account #" << accountNumber << "has no information." << endl;
}
}
// create and insert record
void newRecord(fstream& insertInFile) {
int accountNumber{getAccount("Enter new account number")};
insertInFile.seekg((accountNumber - 1)* sizeof(ClientData)); // move file-pos pointer to correct record in file
ClientData client;
insertInFile.read(reinterpret_cast<char*> (&client), sizeof(ClientData)); // read record from file
if (client.getAccountNumber() == 0) {
string lastName;
string firstName;
double balance;
cout << "Enter last name, first name and balance";
cin >> setw(15) >> lastName;
cin >> setw(10) >> firstName;
cin >> balance;
client.setLastName(lastName);
client.setFirstName(firstName);
client.setBalance(balance);
client.setAccountNumber(accountNumber);
insertInFile.seekp((accountNumber - 1)*sizeof(ClientData));
insertInFile.write(reinterpret_cast<char*>(&client), sizeof(ClientData));
}
else{
cerr << "Account #" << accountNumber << "already contains information." << endl;
}
}
// delete an existing record
void deleteRecord(fstream& deleteFromFile){
int accountNumber{getAccount("Enter account to delete")};
deleteFromFile.seekg((accountNumber - 1)* sizeof(ClientData));
// Read record from file
ClientData client;
deleteFromFile.read(reinterpret_cast<char*>(&client), sizeof(ClientData));
// delete record if record exists
if (client.getAccountNumber() != 0) {
ClientData blankClient;
deleteFromFile.seekp((accountNumber - 1 )*sizeof(ClientData));
deleteFromFile.write(reinterpret_cast<char*>(&blankClient), sizeof(ClientData));
cout << "Account #" << accountNumber << "delete .\n";
}
else {
cerr << "Account # " << accountNumber << " is empty.\n";
}
}