In my program, I have a vector of structs, and I'm trying to iterate through the vector while accessing the properties of each struct. However, the way I'm trying to do this doesn't seem to work. The struct in question is called "person", and it has properties including "Name" and "PartyID", which are the ones I'm trying to access.
I read somewhere online you could do this using pointers to the iterator, so that's what I tried to do (*it.Name and *it.PartyID), but the program won't compile. What am I doing wrong? Here are the errors I'm getting (using G++ to compile the program):
And here is the code I've written:
// DelibDem.cpp : Defines the entry point for the application.
//
#include "DelibDem.h"
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <vector>
//initializing variables
using namespace std;
bool continue_ = true;
string name = "";
string partyID = "";
int numD = 0;
int numR = 0;
int difference = 0;
int vectorSize = 0;
int newVectorSize = 0;
int vectorPos = 0;
int demPos = 0;
int repPos = 0;
struct person{
string Name;
string PartyID;
string equivalentName;
string equivalenceClass;
};
vector<person> Sample;
int main()
{
//user adds people to the vector
while (continue_ == true) {
string personName;
string personPartyID;
string answer;
person inputtedPerson;
cout << "Enter a person's name: ";
std::getline(cin, personName);
//cout << personName;
cout << "Enter the person's party ID (D or R): ";
std::getline(cin, personPartyID);
//cout << personPartyID;
if (personPartyID == "D") person inputtedPerson = { personName, personPartyID, "", "Republicans" };
else person inputtedPerson = { personName, personPartyID, "", "Democrats" };
Sample.at(vectorPos) = inputtedPerson;
//cout << "{{" << Sample.at(0).Name << ", " << Sample.at(0).PartyID << ", " << Sample.at(0).equivalentName << ", " << Sample.at(0).equivalenceClass << "}\n";
//for (int i = 1; i < Sample.size(); i++) {
// cout << ", {" << Sample.at(i).Name << ", " << Sample.at(i).PartyID << ", " << Sample.at(i).equivalentName << ", " << Sample.at(i).equivalenceClass << "}\n";
//}
//cout << "}";
vectorPos++;
cout << "Do you wish to add more people? (Y/N) ";
cin >> answer;
if (answer == "N") continue_ = false;
cin.ignore();
}
//The number of Democrats in the sample is stored in numD. The number of Republicans is stored in numR.
for (auto& element : Sample)
{
if (element.PartyID == "D") numD++;
else numR++;
}
//print the number of Democrats and Republicans
cout << numD;
cout << numR;
//determine if an equivalence relation exists
if (numD == numR) cout << "An equivalence relation is possible" << endl;
else {
cout << "An equivalence relation is not possible, because ";
if (numD > numR) {
cout << "There are " << numD - numR << " more Democrats than Republicans" << endl;
int difference = numD - numR;
while (difference != 0) {
string specifiedName;
vectorSize = Sample.size();
cout << "Which Democrat do you want to remove from the sample?" << endl;
cin >> specifiedName;
for (std::vector<person>::iterator it = Sample.begin(); it != Sample.end(); ++it) //this is the part I'm asking about
{
if (*it.Name == specifiedName && *it.PartyID == "D") {
Sample.erase(it);
break;
}
}
newVectorSize = Sample.size();
if (vectorSize == newVectorSize) cout << "The requested person is not one of the Democrats in the sample. Please try again." << endl;
else difference--;
}
}
else {
cout << "There are " << numR - numD << " more Republicans than Democrats" << endl;
int difference = numR - numD;
while (difference != 0) {
string specifiedName;
vectorSize = Sample.size();
cout << "Which Republican do you want to remove from the sample?" << endl;
cin >> specifiedName;
for (std::vector<person>::iterator it = Sample.begin(); it != Sample.end(); ++it)
{
if (*it.Name == specifiedName && *it.PartyID == "R") {
Sample.erase(it);
break;
}
}
newVectorSize = Sample.size();
if (vectorSize == newVectorSize) cout << "The requested person is not one of the Republicans in the sample. Please try again." << endl;
else difference--;
}
}
cout << "The number of Democrats and Republicans is now equal and an equivalence relation is possible." << endl;
}
//print the properties of each element in the sample
for (auto& element : Sample)
{
cout << element.Name << endl;
cout << element.PartyID << endl;
cout << element.equivalentName << endl;
cout << element.equivalenceClass << endl;
cout << "\n";
}
//creating two vectors containing only the Democrats and Republicans, respectively
vector<person> Democrats;
vector<person> Republicans;
for (auto& element : Sample)
{
if (element.PartyID == "D") {
Democrats.at(demPos) = element;
demPos++;
}
else {
Republicans.at(repPos) = element;
repPos++;
}
}
//assigning each Democrat to a Republican and vice versa
for (int i = 0; i < Democrats.size(); i++)
{
Democrats.at(i).equivalentName = Republicans.at(i).Name;
}
for (int i = 0; i < Republicans.size(); i++)
{
Republicans.at(i).equivalentName = Democrats.at(i).Name;
}
return 0;
//printing the properties of each element in the sample again
for (auto& element : Sample)
{
cout << element.Name << endl;
cout << element.PartyID << endl;
cout << element.equivalentName << endl;
cout << element.equivalenceClass << endl;
cout << "\n";
}
}
Ok So I have abit of a problem with my code that I cant seem to find the solution for. Im writing a program that will work like a phonebook for your phone. And everything that happens will be saved in a .txt file. So when the program starts it will always read from the same file and put that into class objects called "person" and then you will be able to edit/delete/add new contacts and then it gets rewriten to the file.
The problem im having right now is that I want to make more of the code into functions instead of having it all in the main folder. So as you can see from the two last functions, one should read from the file and the other should write to the file. What I want to do is to replace all the code in main() that has to do with readToFile and writeToFile. Also i would like to be able to put the writeToFile function after every case switch action like edit/delete/add. So that you dont have to choose to write to the file. It just does that automatically.
Can I somehow use pointers/references for this or how do i get access to the "person" objects in my functions.
First time asking a question here so feel free to educate me if i did something wrong.
Here is the code:
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
void printline(char, int);
bool name_valid(string);
class contact
{
public:
string fName, lName, adress, epost, mobileNo, birthday;
//initialize the contact by a default value
contact() : fName(""), lName(""), adress(""), epost(""), mobileNo(""), birthday("")
{}
// Write all contacts to the file.
bool writeToFile()
{
if (fName != "")
{
cout << "Name: " << fName << " " << lName << "\n" << "Mobilenumber: " << mobileNo << "\n" << "Adress: " << adress << "\n" << "Email: " << epost << "\n" << "Birthday: " << birthday << endl;
return 1; //Success!!
}
else
{
cout << " Fail!" << endl;
return 0; //Fail!!
}
}
//Show all contacts
bool showAll()
{
if (fName != "")
{
cout << "Name: " << fName << " " << lName << "\n" << "Mobilenumber: " << mobileNo << "\n" << "Adress: " << adress << "\n" << "Email: " << epost << "\n" << "Birthday: " << birthday << endl;
return 1; //Success!!
}
else
return 0; //Fail!!
}
// Search
bool Search(string search_word)
{
if (search_word == fName)
{
cout << "Name: " << fName << " " << lName << "\n" << "Mobilenumber: " << mobileNo << "\n" << "Adress: " << adress << "\n" << "Email: " << epost << "\n" << "Birthday: " << birthday << endl;
return 1;
}
else
return 0;
}
// Check if a name exists or not
bool name_exists(string tname)
{
if (tname == fName)
return 1;
else
return 0;
}
// The contact object is initialized by valid values
bool addContact(string new_fName, string new_lName, string new_adress, string new_epost, string new_mobileNo, string new_birthday )
{
if (fName == "")
{
fName = new_fName;
lName = new_lName;
adress = new_adress;
epost = new_epost;
mobileNo = new_mobileNo;
birthday = new_birthday;
return 1; // Success !!
}
else
return 0; // Failure !!
}
//edits the contact details
bool edit(string);
bool erase(string new_name)
{
if (new_name == fName)
{
fName = "";
lName = "";
adress = "";
epost = "";
mobileNo = "";
birthday = "";
return 1;
}
else
return 0;
}
};
// Edits the contact
bool contact::edit(string name_check)
{
string new_fName, new_lName, new_adress, new_epost, new_mobileNo, new_birthday;
if (name_check == fName)
{
cin.ignore();
cin.clear();
cout << "Enter new first name: ";
getline(cin,new_fName);
cout << "Enter new lastname: ";
getline(cin,new_lName);
cout << "Enter new adress: ";
getline(cin,new_adress);
cout << "Enter new epost: ";
getline(cin,new_epost);
cout << "Enter new birthday: ";
getline(cin,new_birthday);
fName = new_fName;
lName = new_lName;
adress = new_adress;
epost = new_epost;
birthday = new_birthday;
return 1;
}
else
return 0;
}
int main()
{
contact person[100];
ifstream infile("Phonebook.txt");
string temp_fName, temp_lName, temp_adress, temp_epost, temp_mobilNo, temp_birthday;
int counter, choice, i;
bool flag;
bool cancel_flag;
// Read from file to contact person
string ignoreName, ignoreCell, ignoreAdress, ignoreEmail, ignoreBirthday;
string fileFirstname, fileLastname, fileCell, fileAdress, fileEmail, fileBirthday;
// Goes through the text file and put all the names in the contact class
while (!infile.eof())
{
getline(infile, ignoreName, ' ');
getline(infile, fileFirstname, ' ');
getline(infile, fileLastname);
getline(infile, ignoreCell, ' ');
getline(infile, fileCell);
getline(infile, ignoreAdress, ' ');
getline(infile, fileAdress);
getline(infile, ignoreEmail, ' ');
getline(infile, fileEmail);
getline(infile, ignoreBirthday, ' ');
getline(infile, fileBirthday);
// Check if the file is empty
if (!infile)
{
break;
}
for (i = 0; i < 100; i++)
if (person[i].addContact(fileFirstname, fileLastname, fileAdress, fileEmail, fileCell, fileBirthday))
{
cout << "\nContact added successfully!" << endl;
flag = 1;
break;
}
}
infile.close();
ofstream outfile("Phonebook.txt");
cout << "=========== Your Phonebook ==========" << endl;
do
{
cout << "\n\n";
printline('-', 25);
cout << "1. Add Contact" << endl
<< "2. Edit Contact" << endl
<< "3. Delete Contact" << endl
<< "4. Search" << endl
<< "5. Show All Contacts" << endl
<< "6. Write All Contacts To File." << endl
<< "0. Exit" << endl << endl
<< "Your choice... ";
cin >> choice;
system("cls");
printline('-', 20);
cancel_flag = 0;
flag = 0;
counter = 0;
switch (choice)
{
case 0:
return 0;
break;
// Adds a new contact
case 1:
cout << "Add New Contact\t\t\t\tpress - to cancel" << endl;
printline('-', 25);
counter = 0;
// Loop until correct contact info is untered
do
{
flag = 0;
if (counter)
cout << "Try again \t\t\t\tpress - to cancel" << endl;
//count how many times the do-while loop executes
counter++;
cin.ignore();
cin.clear();
cout << "First Name: ";
getline(cin, temp_fName);
cout << "Last Name: ";
getline(cin, temp_lName);
cout << "Adress: ";
getline(cin, temp_adress);
cout << "Email: ";
getline(cin, temp_epost);
cout << "Mobile Number: ";
getline(cin, temp_mobilNo);
cout << "Birthday: ";
getline(cin, temp_birthday);
if (temp_fName == "-")
{
cancel_flag = 1;
break;
}
for (i = 0; i < 100; i++)
{
if (person[i].name_exists(temp_fName))
{
cout << "The name you entered is already there"
"in the phonebook, entere a different name." << endl;
flag = 1;
break;
}
}
} while (!name_valid(temp_fName) || flag);
if (cancel_flag)
{
system("cls");
break;
}
//This loop adds the contact to the phonebook
for (i = 0; i < 100; i++)
if(person[i].addContact(temp_fName, temp_lName, temp_adress, temp_epost, temp_mobilNo, temp_birthday))
{
cout << "\nContact added successfully!" << endl;
flag = 1;
break;
}
if (!flag)
cout << "Memory full! Delete some contacts first." << endl;
break;
// Edits an existing contact
case 2:
cout << "Enter a contact name to edit \t\t\t\tpress - to cancel" << endl;
cin >> temp_fName;
// Cancel operation
if (temp_fName == "-")
{
system("cls");
break;
}
for (i = 0; i < 100; i++)
if (person[i].edit(temp_fName))
{
cout << "Edited Successfully!" << endl;
flag = 1;
break;
}
if (!flag)
cout << "Contact name not found!" << endl;
break;
//Delete a contact
case 3:
do
{
if (counter)
cout << "Try again" << endl;
counter++;
cout << "Enter a contact name to delete: \t\t\t\tpress - to cancel" << endl;
cin >> temp_fName;
// Cancel operation
if (temp_fName == "-")
{
system("cls");
break;
}
//Final Confirmation
for (i = 0; i < 100; i++)
if (person[i].name_exists(temp_fName))
{
flag = 1;
cout << "Are you sure you want to delete (1/0)" << endl;
int yes;
cin >> yes;
if (!yes)
{
system("cls");
cancel_flag = 1;
}
break;
}
if (!flag)
cout << "Contact name not found!" << endl;
if (cancel_flag)
break;
// This code deletes the contact
if (flag)
{
for (i = 0; i < 100; i++)
if (person[i].erase(temp_fName))
{
cout << "Deleted successfully!" << endl;
break;
}
}
} while (!flag);
break;
// Search a contact
case 4:
do
{
if (counter)
cout << "Try again" << endl;
counter++;
cout << "Search a name: \t\t\t\tpress - to cancel" << endl;
cin >> temp_fName;
// Cancel operation
if (temp_fName == "-")
{
system("cls");
break;
}
for (i = 0; i < 100; i++)
if (person[i].Search(temp_fName))
{
flag = 1;
break;
}
if (!flag)
cout << "Contact namew not found!" << endl;
} while (!flag);
break;
// Show all the contacts
case 5:
cout << "Showing Contacts" << endl;
printline('-', 25);
for (i = 0; i < 100; i++)
{
if (person[i].showAll())
{
flag = 1;
cout << "\n\n";
}
}
if (!flag)
cout << "No contacts found!" << endl;
break;
case 6:
// Write to file
cout << "Writing to file." << endl;
printline('-', 25);
for (int i = 0; i < 100; i++)
{
if (person[i].fName != "")
{
outfile << "Name: " << person[i].fName << " " << person[i].lName << "\n" << "Mobilenumber: " << person[i].mobileNo << "\n" << "Adress: " << person[i].adress << "\n" << "Email: " << person[i].epost << "\n" << "Birthday: " << person[i].birthday << "\n\n\n\n";
flag = 1;
cout << "\n\n";
}
}
break;
}
}while (1);
return 0;
}
//prints a line
void printline(char ch, int size)
{
for (int i = 0; i < size; i++)
cout << ch;
cout << "\n";
}
//Contact name validation
bool name_valid(string tname)
{
if (tname.size() > 20)
{
cout << "Invalid name!\nEnter a name within 20 characters!" << endl;
return 0;
}
else if (tname == "")
{
cout << "Invalid Name!\nName cannot be blank" << endl;
return 0;
}
else
return 1;
}
void writeToFile()
{
cout << "Writing to file." << endl;
printline('-', 25);
for (int i = 0; i < 100; i++)
{
if (person[i].fName != "")
{
outfile << "Name: " << person[i].fName << " " << person[i].lName << "\n" << "Mobilenumber: " << person[i].mobileNo << "\n" << "Adress: " << person[i].adress << "\n" << "Email: " << person[i].epost << "\n" << "Birthday: " << person[i].birthday << "\n\n\n\n";
flag = 1;
cout << "\n\n";
}
}
}
void readfromfile()
{
ifstream infile("Phonebook.txt");
string ignoreName, ignoreCell, ignoreAdress, ignoreEmail, ignoreBirthday;
string fileFirstname, fileLastname, fileCell, fileAdress, fileEmail, fileBirthday;
// Goes through the text file and put all the names in the contact class
while (!infile.eof())
{
getline(infile, ignoreName, ' ');
getline(infile, fileFirstname, ' ');
getline(infile, fileLastname);
getline(infile, ignoreCell, ' ');
getline(infile, fileCell);
getline(infile, ignoreAdress, ' ');
getline(infile, fileAdress);
getline(infile, ignoreEmail, ' ');
getline(infile, fileEmail);
getline(infile, ignoreBirthday, ' ');
getline(infile, fileBirthday);
// Check if the file is empty
if (!infile)
{
break;
}
for (int i = 0; i < 100; i++)
if (person[i].addContact(fileFirstname, fileLastname, fileAdress, fileEmail, fileCell, fileBirthday))
{
cout << "\nContact added successfully!" << endl;
flag = 1;
break;
}
}
infile.close();
}
Just pass in an array to the function (and others which are needed). Now the size of the array is known beforehand so we can protect it from array decay too. It'll look something like this,
void writeToFile(contact(&person)[100], std::fstream& outfile, bool& flag) { ... }
void readfromfile(contact(&person)[100], bool& flag) { ... }
Note that were passing in the others (flag and outfile) using the reference so that the actual variable can be altered.
From the two, I would recommend using the second option. Its clean, simple and safe (if you may).
Note: Try not to use using namespace std;. It not a good practice and basically your taking the std namespace and putting it in the global namespace. Now that namespace is huuuuggeeeeee. Later to access its objects and stuff, use :: operator.
#pragma once
#ifndef SDDS_GIFT_H
#define SDDS_GIFT_H
#include <iostream>
namespace sdds
{
const int MAX_DESC = 15;
const double MAX_PRICE = 999.999;
const int MAX_WRAP = 20;
struct Gift
{
char m_description[MAX_DESC];
double m_price;
int m_units;
int m_wrapLayers;
struct Wrapping* m_wrap;
};
struct Wrapping
{
char* m_pattern;
};
void gifting(char*);
void gifting(double&);
void gifting(int&);
bool wrap(Gift& theGift);
bool unwrap(Gift& theGift);
void gifting(Gift& theGift);
void display(const Gift& theGift);
}
#endif
<pre><code>
#include <iostream>
#include "Gift.h"
using namespace std;
namespace sdds
{
void gifting(char* m_description) // sending info
{
cout << "Enter gift description: ";
cin.width(MAX_DESC + 1);
cin >> m_description;
}
void gifting(double& m_price)
{
cout << "Enter gift price: ";
cin >> m_price;
while (m_price > MAX_PRICE || m_price < 0)
{
cout << "Gift price must be between 0 and " << MAX_PRICE << std::endl;
cout << "Enter gift price: ";
cin >> m_price;
}
}
void gifting(int& m_units)// gifting function
{
cout << "Enter gift units: ";
cin >> m_units;
while (m_units < 1)
{
cout << "Gift units must be at least 1" << std::endl;
cout << "Enter gift units: ";
cin >> m_units;
};
}
bool wrap(Gift& m_wrap) {
if (m_wrap.m_wrapLayers > 0) {
cout << "Gift is already wrapped!" << endl;
return false;
}
else {
cout << "Wrapping gifts..." << endl;
cout << "Enter the number of wrapping layers for the Gift: ";
cin >> m_wrap.m_wrapLayers;
while (m_wrap.m_wrapLayers < 1) {
cout << "Layers at minimum must be 1, try again." << endl;
cout << "Enter the number of wrapping layers for the Gift: ";
cin >> m_wrap.m_wrapLayers;
}
int i = 0;
m_wrap.m_wrap = new Wrapping[MAX_WRAP + 1];
for (i = 0; i < m_wrap.m_wrapLayers; i++) {
m_wrap.m_wrap->m_pattern = new char[MAX_WRAP + 1];
cout << "Enter wrapping pattern #" << i + 1 << ": ";
cin >> m_wrap.m_wrap->m_pattern;
} // I put struct in a structure
return true;
}
delete[]m_wrap.m_wrap;
m_wrap.m_wrap = nullptr;
}
bool unwrap(Gift& g_unwrap) // unwrap function
{
if (g_unwrap.m_wrapLayers > 0) {
cout << "Gift being unwrapped." << endl;
g_unwrap.m_wrapLayers = 0;
g_unwrap.m_wrap->m_pattern = nullptr;
return true;
}
else
{
cout << "Gift isn't wrapped! Can't unwrap." << endl;
return false;
}
}
void display(const Gift& theGift)
{
cout << "Gift Details:" << endl;
cout << " Description: " << theGift.m_description << endl;
cout << " Price: " << theGift.m_price << endl;
cout << " Units: " << theGift.m_units << endl;
if (theGift.m_wrap == nullptr) // this part seems like a problem
{
cout << "Unwrapped" << endl;
}
else
{
int i = 0;
cout << "Wrap Layers: " << theGift.m_wrapLayers << endl;
for (i = 0; i < theGift.m_wrapLayers; i++) {
cout << "Wrap #" << i + 1 << ": " << theGift.m_wrap[i].m_pattern << endl;
}
}
}
void gifting(Gift& gift) //last function
{
cout << "Preparing a gift..." << endl;
gifting(gift.m_description);
gifting(gift.m_price);
gifting(gift.m_units);
wrap(gift);
}
}
</code></pre>
/***********************************************************************
// Workshop 2: Dynamic Memory & Function Overloading
// Version 2.0
// Date 2020/05/05
// Author Michael Huang
// Description
// Tests Gift module and provides a set of TODOs to complete
// which the main focuses are dynamic memory allocation
//
/////////////////////////////////////////////////////////////////
***********************************************************************/
#include <iostream>
#include "Gift.h"
#include "Gift.h" // intentional
using namespace std;
using namespace sdds;
void printHeader(const char* title)
{
char oldFill = cout.fill('-');
cout.width(40);
cout << "" << endl;
cout << "|> " << title << endl;
cout.fill('-');
cout.width(40);
cout << "" << endl;
cout.fill(oldFill);
}
<pre><code>
int main() {
Gift g1; // Unwrapped Gift
{
printHeader("T1: Checking Constants");
cout << "MAX_DESC: " << sdds::MAX_DESC << endl;
cout << "MAX_PRICE: " << sdds::MAX_PRICE << endl;
cout << "MAX_WRAP: " << sdds::MAX_WRAP << endl;
cout << endl;
}
{
printHeader("T2: Display Wrapped Gift");
gifting(g1.m_description);
gifting(g1.m_price);
gifting(g1.m_units);
cout << endl;
g1.m_wrap = nullptr;
g1.m_wrapLayers = 0;
display(g1);
cout << endl;
}
{
printHeader("T3: Wrap a gift");
if (wrap(g1))
cout << "Test succeeded!";
else
cout << "Test failed: wrapping didn't happen!" << endl;
cout << endl << endl;
}
{
printHeader("T4: Re-wrap a gift");
cout << "Attempting to rewrap the previous Gift: "
<< g1.m_description << endl;
if (wrap(g1) == false)
cout << "Test succeeded!";
else
cout << "Test failed: gift it's already wrapped, cannot wrap again!";
cout << endl << endl;
}
{
printHeader("T5: Unwrap a gift");
cout << "Attempting to unwrap the previous gift: "
<< g1.m_description << endl;
if (unwrap(g1))
cout << "Test succeeded!";
else
cout << "Test failed: you should be able to unwrap!";
cout << endl << endl;
}
{
printHeader("T6: Unwrap again");
cout << "Attempting to un-unwrap the previous gift: "
<< g1.m_description << endl;
if (!unwrap(g1))
cout << "Test succeeded!";
else
cout << "Test failed: you should not be able to unwrap again!";
cout << endl << endl;
}
Gift g2; // Unwrapped Gift
{
printHeader("T7: Prepare another gift");
g2.m_wrap = nullptr;
g2.m_wrapLayers = 0;
gifting(g2);
cout << endl;
display(g2);
cout << endl;
}
{
printHeader("T8: Unwrap the second gift");
unwrap(g2);
}
return 0;
}
Output matches perfectly but I don't know why memory leaks.. please help me. I am doubting my wrap part but I think there must be something else since deallocation seems fine.
I tried my best but I still cannot see which part is wrong.
I cannot see why my deallocation does not work I tried changing it so many times but nothing works.
On this line:
m_wrap.m_wrap->m_pattern = new char[MAX_WRAP + 1];
You allocate memory, but later you only:
delete[]m_wrap.m_wrap;
Also in your for loop you allocate memory, then get some input and store that inside the pointer, as a memory address. Should you ever dereference that, you will invoke undefined behavior, in practice that may likely will a segfault. You should consider rewriting at least that part from scratch.
I was able to write a program to pass my c++ class in college except for one feature. I was unable to create a function that sorted the names inside an array of structs with name of type char alphabetically. Please advise on how to tackle this problem.
I would need a function that sorts the accountRecords array alphabetically.
#include <iostream>
#include <ctime>
#include <fstream>
#include <string>
#include <vector>
#include <string>
#include <iomanip>
using namespace std;
//Structure Initilizations
const int NAME_SIZE = 25, ADDR_SIZE = 100, CITY_SIZE = 51, STATE_SIZE = 4, DATE_SIZE = 16, CUSTOMER_ID = 10, TRANSACTION_TYPE = 16;
struct MasterRecord
{
int customerID;
char name[NAME_SIZE]; // SORT THIS FIELD ALPHABETICALLY
char address[ADDR_SIZE];
char city[ADDR_SIZE];
char state[STATE_SIZE];
char zip[STATE_SIZE];
float accountBalance;
char lastTransactionDate[15];
};
struct TransactionRecord
{
int customerID;
char transactionType;
float amount;
char transactionDate[15];
};
//File Array Initializations
vector<MasterRecord> masterRecordList(101);
vector<TransactionRecord> transRecordList(101);
//Array List Record Position
int masterRecordArrayPosition = 0;
int transactionRecordArrayPosition = 0;
//User Menu Answer Variable Initialization
int userAnswer = 0;
string recordNotFoundAnswer = "";
//Print Function Prototypes
void showMenu();
void showMasterRecord(int);
void showTransactionRecord(int);
//Main Menu Function Prototypes
void newCustomerRecord(int);
void editCustomerRecord(int);
void deleteCustomerRecord(int);
int randomComputerID();
int searchMasterRecord(int);
void saveAccountRecords();
void saveTransRecords();
void newTransactionRecord(int);
//Placeholders Variables
int customerIDsearch = 0;
int customerIDSearchArrayPosition = 0;
int userNameCharactererror = 0;
//Function Loop Counters
int accountWriteCounter = 0;
int transWriteCounter = 0;
int showRecordCounter = 0;
int showTransCounter = 0;
//System time Declaration and Conversion for [lastTransactionDate]
time_t now = time(0);
tm *ltm = localtime(&now);
string currentYearInString = to_string(1900 + ltm->tm_year);
string currentMonthInString = to_string(1 + ltm->tm_mon);
string currentDayInString = to_string(ltm->tm_mday);
string currentDateInString = currentMonthInString + "/" + currentDayInString + "/" + currentYearInString;
char dateInChar[15];
//Main Program
int main()
{
//Final conversion of time in string to char for storage
strncpy_s(dateInChar, currentDateInString.c_str(), 15);
//Open MasterRecord file and read records to arrays
fstream masterRecord("masterRecord.dat", ios::in | ios::binary);
int listCounter = 0;
if (!masterRecord) {
cout << "Unable to open the user records file, creating file database....Done!" << endl;
masterRecord.open("masterRecord.dat", ios::out | ios::binary);
}
else {
while (!masterRecord.eof()) {
masterRecord.read(reinterpret_cast<char *>(&masterRecordList[listCounter]), sizeof(masterRecordList[0]));
if (masterRecordList[listCounter].customerID != 0) {
listCounter++;
}
masterRecordArrayPosition = listCounter;
}
masterRecord.close();
}
//Open Transaction Record and read to arrays
fstream transactionRecord("transactionRecord.dat", ios::in | ios::binary);
int listCounter2 = 0;
if (!transactionRecord) {
cout << "Unable to open the transaction file, creating file database....Done!" << endl << endl;
transactionRecord.open("transactionRecord.dat", ios::out | ios::binary);
}
else {
while (!transactionRecord.eof()) {
transactionRecord.read(reinterpret_cast<char *>(&transRecordList[listCounter2]), sizeof(transRecordList[0]));
if (transRecordList[listCounter2].customerID != 0) {
listCounter2++;
}
transactionRecordArrayPosition = listCounter2;
}
transactionRecord.close();
}
//Time Declaration Used to Generate Random IDs
srand((unsigned)time(0));
//Main user Program Loop
while (userAnswer != 6) {
showMenu();
cin >> userAnswer; cout << endl;
//Menu Input Data Validation
if (cin.fail()) {
cout << "Please only enter numbers 1-6 for the corresponding menu selection." << endl;
cin.clear();
cin.ignore();
}
else {
if (userAnswer < 1 || userAnswer > 7) {
cout << "Please only enter numbers 1-6 for the corresponding menu selection." << endl;
userAnswer = 0;
}
}
//Menu Selection Switch Case
switch (userAnswer) {
case 1:
newCustomerRecord(masterRecordArrayPosition);
cout << "Record has been saved." << endl << endl;
break;
case 2:
newTransactionRecord(transactionRecordArrayPosition);
break;
case 3:
cout << "Please enter the Customer ID you would like to Delete" << endl << endl; //[Delete Customer Record] Function goes here
cin >> customerIDsearch;
customerIDSearchArrayPosition = searchMasterRecord(customerIDsearch);
if (customerIDSearchArrayPosition != 9999) {
deleteCustomerRecord(customerIDSearchArrayPosition);
}
break;
case 4:
cout << "Please enter the Customer ID you would like to edit." << endl << endl; //[Search/Edit Customer Record] Function goes here
cin >> customerIDsearch;
customerIDSearchArrayPosition = searchMasterRecord(customerIDsearch);
if (customerIDSearchArrayPosition != 9999) {
editCustomerRecord(customerIDSearchArrayPosition);
}
else {
cout << "Record was not found, would you like to add a new record? Y = Yes, N = No" << endl << endl;
cin >> recordNotFoundAnswer;
if (recordNotFoundAnswer == "Y" | recordNotFoundAnswer == "y") {
newCustomerRecord(masterRecordArrayPosition);
cout << "Record has been saved." << endl << endl;
}
else if (recordNotFoundAnswer == "N" | recordNotFoundAnswer == "n") {
userAnswer = 0;
}
}
break;
case 5:
cout << setw(212) << "Please find all customer records in the database" << endl << endl; //[Show all Records] Function goes here
cout << setw(40) << "Name:" << setw(10) << "ID:" << setw(23) << "Street Address:" <<setw(10) << "ZIP:" << setw(16) << "L.Trans Date:" << setw(11) << "Balance: " << endl;
while (showRecordCounter < 100) {
if (masterRecordList[showRecordCounter].customerID != 0) {
showMasterRecord(showRecordCounter);
}
showRecordCounter = showRecordCounter + 1;
} showRecordCounter = 0;
userAnswer = 0;
cout << endl;
break;
case 6:
cout << "Saving changes to database...Done!" << endl;
saveAccountRecords();
saveTransRecords();
cout << "Done!" << endl;
break;
case 7:
cout << "Showing all transaction Records:" << endl << endl;
while (showTransCounter < 100) {
if (transRecordList[showTransCounter].customerID != 0) {
showTransactionRecord(showTransCounter);
}
showTransCounter = showTransCounter + 1;
} showTransCounter = 0;
userAnswer = 0;
break;
}
}
return 0;
}
//Databas Management Functions
void saveAccountRecords() {
fstream masterRecord("masterRecord.dat", ios::out | ios::binary);
while (accountWriteCounter < 100) {
masterRecord.write(reinterpret_cast<char *>(&masterRecordList[accountWriteCounter]), sizeof(masterRecordList[0]));
accountWriteCounter++;
}
masterRecord.close();
}
void saveTransRecords() {
fstream transRecord("transactionRecord.dat", ios::out | ios::binary);
while (transWriteCounter < 100) {
transRecord.write(reinterpret_cast<char *>(&transRecordList[transWriteCounter]), sizeof(transRecordList[0]));
transWriteCounter++;
}
transRecord.close();
}
//Random Function
int randomComputerID() {
int randomNumber;
randomNumber = (rand() % 1000) + 10000;
return randomNumber;
}
//Program Print Functions
void showMenu() {
cout << "Welcome to your C++ company terminal! Please enter one of the options below to continue." << endl << endl;
cout << "1. New Customer Record" << endl;
cout << "2. New Transaction Record" << endl;
cout << "3. Delete Customer Record" << endl;
cout << "4. Edit Customer Record" << endl;
cout << "5. Show all Account Records in Database" << endl;
cout << "6. Exit and Save Changes to Database" << endl << endl;
cout << "Please enter the number for the correspondent action you would like to perform:" << endl;
}
void showMasterRecord(int arrayNum) {
cout << setw(40)
<< masterRecordList[arrayNum].name << setw(10) << masterRecordList[arrayNum].customerID << setw(23)
<< masterRecordList[arrayNum].address << setw(10)
<< masterRecordList[arrayNum].zip << setw(16)
<< masterRecordList[arrayNum].lastTransactionDate << setw(6) <<"$"
<< masterRecordList[arrayNum].accountBalance; cout << endl;
}
void showTransactionRecord(int arrayNum) {
cout << "Customer ID: " << transRecordList[arrayNum].customerID << endl;
cout << "Amount: $" << transRecordList[arrayNum].amount << endl;
cout << "Transaction Type: " << transRecordList[arrayNum].transactionType << endl;
cout << "Transaction Date: " << transRecordList[arrayNum].transactionDate << endl << endl;
}
//Main Menu Functions [Please insert your functions here and prototype them above].
void newCustomerRecord(int arrayNum) {
cout << "Customer ID: ";
masterRecordList[arrayNum].customerID = randomComputerID();
cout << masterRecordList[arrayNum].customerID; cout << endl;
cin.ignore();
do
{
cout << "Name: ";
cin.getline(masterRecordList[arrayNum].name, 25);
if (cin.fail()) {
cout << endl << "Please enter only characters up 25 chracters for your name." << endl;
userNameCharactererror = 1;
cin.clear();
cin.ignore(80, '\n');
}
else {
userNameCharactererror = 0;
}
} while (userNameCharactererror == 1);
cout << "Address: ";
cin.getline(masterRecordList[arrayNum].address, 100);
cout << "City: ";
cin >> masterRecordList[arrayNum].city;
cout << "State: ";
cin >> masterRecordList[arrayNum].state;
cout << "Zip Code: ";
cin >> masterRecordList[arrayNum].zip;
cout << "Opening Balance: $";
cin >> masterRecordList[arrayNum].accountBalance; cout << endl; cout << endl;
masterRecordArrayPosition = masterRecordArrayPosition + 1;
}
void editCustomerRecord(int arrayNum) {
cout << "Customer ID: ";
cout << masterRecordList[arrayNum].customerID; cout << endl;
cin.ignore();
cout << "Name: ";
cin.getline(masterRecordList[arrayNum].name, 51);
cout << "Address: ";
cin.getline(masterRecordList[arrayNum].address, 100);
cout << "City: ";
cin >> masterRecordList[arrayNum].city;
cout << "State: ";
cin >> masterRecordList[arrayNum].state;
cout << "Zip Code: ";
cin >> masterRecordList[arrayNum].zip;
cout << "Edit Balance: $";
cin >> masterRecordList[arrayNum].accountBalance; cout << endl; cout << endl;
}
void deleteCustomerRecord(int arrayNum) {
if (masterRecordList[arrayNum].accountBalance == 0)
{
masterRecordList[arrayNum].customerID = 0;
cout << "Record has been deleted" << endl << endl;
}
else {
cout << "Unable to delete record, customer accounts holds a positive balance" << endl << endl;
}
}
int searchMasterRecord(int customerID) //Search by customer name and returns array position
{
int arrayPosition = 0;
int arrayCounter = 0;
int customerIdPlaceholder = 0;
while (arrayCounter < 100) {
customerIdPlaceholder = masterRecordList[arrayCounter].customerID;
if (customerIdPlaceholder == customerID) {
cout << "Record has been found!" << endl << endl;
arrayPosition = arrayCounter;
arrayCounter = 100;
}
else {
arrayPosition = 9999;
}
arrayCounter = arrayCounter + 1;
}
return arrayPosition;
};
void newTransactionRecord(int arrayNum) {
// Request customer ID and transaction type from the user
cout << "Customer ID: ";
cin >> transRecordList[arrayNum].customerID;
cin.ignore();
cout << "Date: ";
strncpy_s(transRecordList[arrayNum].transactionDate, dateInChar, 15);
cout << transRecordList[arrayNum].transactionDate << endl;
cout << "Transaction Type [D = Deposit] [W = Withdrawal]: ";
cin >> transRecordList[arrayNum].transactionType;
cout << "Amount: $";
cin >> transRecordList[arrayNum].amount;
//Search for customer account, update balance, and assign last transaction date
customerIDSearchArrayPosition = searchMasterRecord(transRecordList[arrayNum].customerID);
if (customerIDSearchArrayPosition != 9999) {
if (transRecordList[arrayNum].transactionType == 'D') {
masterRecordList[customerIDSearchArrayPosition].accountBalance = masterRecordList[customerIDSearchArrayPosition].accountBalance + transRecordList[arrayNum].amount;
strncpy_s(masterRecordList[customerIDSearchArrayPosition].lastTransactionDate, dateInChar, 9);
cout << "Deposit Successful! " << endl << endl;
}
else if (transRecordList[arrayNum].transactionType == 'W') {
masterRecordList[customerIDSearchArrayPosition].accountBalance = masterRecordList[customerIDSearchArrayPosition].accountBalance - transRecordList[arrayNum].amount;
strncpy_s(masterRecordList[customerIDSearchArrayPosition].lastTransactionDate, dateInChar, 9);
cout << "Withdrawl Successful" << endl << endl;
}
}
else {
cout << "Customer account record was not found, transaction was not saved." << endl << endl;
}
transactionRecordArrayPosition = transactionRecordArrayPosition + 1;
}
Something along these lines:
std::sort(masterRecordList.begin(),
masterRecordList.begin() + masterRecordArrayPosition,
[](const MasterRecord& l, const MasterRecord& r) {
return strcmp(l.name, r.name) < 0;
});
Hi im creating a cinema ticket operator as a self short project but i am a bit stuck on how to make the results of what the user inputs show up at the end summed up like on a receipt. Thanks in advance.
This is my code :
#include <iostream>
#include <string>
using namespace std;
int selectStaff();
int selectDate();
int selectMovie();
int printReceipt(int a);
string name, date;
int main()
{
int movie;
selectStaff();
date = selectDate();
movie = selectMovie();
printReceipt(movie);
return 0;
}
int printReceipt(int a)
{
if (a == 1) {
cout << "Deadpool" << endl;
}
else {
cout << "Goosebumps" << endl;
}
return 0;
}
int selectStaff() {
cout << "Welcome to FILM Screen Cinema" << endl;
cout << endl;
cout << "ENTER STAFF/OPERATOR'S NAME: " << endl;
cin >> name;
return 0;
}
int selectDate() {
cout << endl;
cout << "ENTER DATE:";
cin >> date;
return 0;
}
int selectMovie() {
int movie;
cout << endl;
cout << "CHOOSE A MOVIE THAT IS SCREENING TODAY:" << endl;
cout << endl;
cout << "Press 1 for first option & 2 for second option" << endl;
cout << endl;
cout << "[1] Deadpool" << endl << "[2] Goosebumps" << endl;
cin >> movie;
return 0;
}
I want all the required input to be displayed at the bottom so when it prints, the user can view the summary. I also need a closing message that says "thank you"
You have all of the variables lined up to do this neatly and simply. Just edit your print receipt function to look something like:
Int printreceipt(int a) {
string title;
if (a==1) {
title = "Deadpool";
} else {
title == "Goosebumps";
}
cout << "Cashier: "; cout << name << endl << endl; //say the operator's name and add a line
cout << "Date: " << date << endl; //say the date
cout << "Movie: " << title; //say the title of the movie
cout << endl << endl; //add a line
cout << "Thank you for choosing this cinema! Enjoy!"; //Thank you message :D
}
To give you results similar to:
Cashier: Guy
Date: May 5, 2017
Movie: Deadpool
Thank you for choosing this cinema! Enjoy!