I'm not quite getting a structure search. I have a task, I need to search for students by full name, year of birth, group number or course number. I can search by group number or course number, but the search by full name and date of birth is problematic.
Here are my code and my input file. (I'm sorry if my code is unprofessional, I'm just learning and I need to pass this task, but I'm having no luck and I have no one to turn to for help)
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
struct Student
{
string name;
string yearob;
int course;
int group;
};
ostream& operator<<(ostream& out, const Student obj)
{
out << obj.name << " " << obj.yearob << " " << obj.group << " " << obj.course;
return out;
}
int main()
{
setlocale(LC_ALL, "");
int search = 0;
string name_s, yearob_s;
int course_s, group_s;
int chek = 1;
while (chek == 1)
{
cout << "Enter 1 to start, 0 to exit > ";
cin >> chek;
switch (chek)
{
case(0):
break;
case(1):
{
int leng = 0;
string s;
ifstream fle("input.txt");
while (getline(fle, s))
{
leng += 1;
}
Student* list = new Student[leng];
int a = 0;
fle.close();
ifstream file("input.txt");
string ss, buff;
while (getline(file, s))
{
buff.assign(s);
list[a].course = buff[0] - '0';
buff.erase(0, 2);
ss += buff[0];
ss += buff[1];
list[a].group = stoi(ss);
ss.clear();
buff.erase(0, 3);
for (int i = 0; i < 4; i++)
list[a].yearob += buff[i];
buff.erase(0, 5);
list[a].name.assign(buff);
a += 1;
buff.clear();
}
cout << "What parameter should be used to find students: 1 - by name, 2 - by year of birth, 3 - by course, 4 - by group number: ";
cin >> search;
switch (search) {
case(1):
cin >> name_s;
for (int i = 0; i <= leng; i++) {
if (list[i].name.find(name_s, 10)) {
cout << list[i].name << ", " << list[i].course << " course, " << list[i].group << " group, " << list[i].yearob << " year of birth; " << endl;
}
else {
continue;
}
}
case(2):
cin >> yearob_s;
for (int i = 0; i <= leng; i++) {
if (list[i].yearob.find(yearob_s, 5)) {
cout << list[i].name << ", " << list[i].course << " course, " << list[i].group << " group, " << list[i].yearob << " year of birth; " << endl;
}
else {
continue;
}
}
case(3): {
cin >> course_s;
for (int i = 0; i <= leng; i++) {
if (course_s == list[i].course) {
cout << list[i].name << ", " << list[i].course << " course, " << list[i].group << " group, " << list[i].yearob << " year of birth; " << endl;
}
else {
continue;
}
}
}
case(4):
cin >> group_s;
for (int i = 0; i <= leng; i++) {
if (group_s == list[i].group) {
cout << list[i].name << ", " << list[i].course << " course, " << list[i].group << " group, " << list[i].yearob << " year of birth; " << endl;
}
else {
continue;
}
}
}
file.close();
continue;
}
default:
{
cout << "Input error" << endl;
continue;
}
}
}
}
Input file:
2 01 1999 Cody Hoyt
2 01 2002 Danielle Robyn Diaz
3 01 1999 Mayra Marie Collins
2 05 2000 Marc Nunez
4 05 2000 Tricia Gilmore
5 04 2001 Dale Lucas
1 01 1998 Ruby Merritt
2 01 2001 Tabitha Jenkins
4 02 1995 George Kris Oneill
2 03 1999 Bonnie Blair
Just maybe a shorter version of your code. I provide it not as a solution to your main question (because the following code is pretty advanced), but as an example of how you could avoid repeating code and making big nested constructions.
Here I moved out the code of reading students from a file into a separate function, and inside it should easily read each student using operator>> from a file. Similarly you can define operator<< to specify in which format you want students to be printed.
The repetitive code of printing filtered students is moved into a single function, that iterates all students and prints only pass a given test. You then give this test as a lambda function in each branch of switch operator
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <functional>
using namespace std;
struct Student
{
string name;
string yearob;
int course;
int group;
};
ostream& operator<<(ostream& out, const Student& stud)
{
out << stud.name << ", " << stud.course << " course, " << stud.group << " group, " << stud.yearob << " year of birth; " << endl;
return out;
}
istream& operator>>(istream& in, Student& stud)
{
in >> stud.course >> stud.group >> stud.yearob >> stud.name;
return in;
}
vector<Student> read_students_file(const string& filename) {
vector<Student> students;
ifstream file(filename);
while (file)
{
students.push_back({}); // insert empty student
file >> students[students.size() - 1]; // fill student
}
file.close();
return students ;
}
void print_filtered(const vector<Student>& students, function<bool(const Student&)> should_print) {
for (const Student& student : students) {
if (should_print(student)) {
cout << student;
}
}
}
int main()
{
setlocale(LC_ALL, "");
while (true)
{
cout << "Enter 1 to start, 0 to exit > ";
int check;
cin >> check;
if (check == 0) {
break;
} else if (check != 1) {
continue;
}
vector<Student> students = read_students_file("input.txt");
cout << "What parameter should be used to find students: 1 - by name, 2 - by year of birth, 3 - by course, 4 - by group number: ";
int search_variant;
cin >> search_variant;
switch (search_variant) {
case(1): {
string find_name;
cin >> find_name;
print_filtered(students,
[&](auto& student){ return student.name == find_name; });
break;
}
case(2): {
string find_yearob;
cin >> find_yearob;
print_filtered(students,
[&](auto& student){ return student.yearob == find_yearob; });
break;
}
case(3): {
int find_course;
cin >> find_course;
print_filtered(students,
[&](auto& student){ return student.course == find_course; });
break;
}
case(4): {
int find_group;
cin >> find_group;
print_filtered(students,
[&](auto& student){ return student.group == find_group; });
break;
}
default: {
cout << "Input error" << endl;
continue;
}
}
}
}
Related
I have an assignment in my c++ class which is: Write a program that declares a struct to store the data of a football player (player’s name, player’s position, number of touchdowns, number of catches, number of passing yards, number of receiving yards, and the number of rushing yards). Declare an array of 10 components to store the data of 10 football players. Your program must contain a function to input data from a file (You will need to create the input file) and functions to output data to the console. Add functions to search the array to find the index of a specific player, and update the data of a player. Before the program terminates, give the user the option to save data in a file (write a function for this). Your program should be menu driven, giving the user various choices. Your main function should mostly have variable declarations and function calls in it. Most operations should be handled by other functions.
I am stuck on getting my program to read the info on my input file. please help
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
struct player {
string name;
string position;
int touchdowns;
int catches;
int pass;
int receive;
int rush;
};
int addData( ifstream& ifile, int count , player football[])
{
if (count == 0)
{
ifile >> football[count].name;
ifile >> football[count].position;
ifile >> football[count].touchdowns;
ifile >> football[count].catches;
ifile >> football[count].pass;
ifile >> football[count].receive;
ifile >> football[count].rush;
count++;
}
else if (count != 0)
{
int i = 0;
string name;
string position;
int touchdowns;
int catches;
int pass;
int receive;
int rush;
while (i != -1)
{
ifile >> name >> position >> touchdowns >> catches >> pass >> receive >> rush;
if((*(&football + 1) - football) > 0)
{
if (name == football[i].name)
{
i++;
}
if (name != football[i].name)
{
football[count].name = name;
football[count].position = position;
football[count].touchdowns = touchdowns;
football[count].catches = catches;
football[count].pass = pass;
football[count].receive = receive;
football[count].rush = rush;
i = -1;
count++;
}
}
}
}
return count;
}
void display(int count, player football[])
{
cout << "There are " << count << " players," << endl;
if (count <= 0)
{
cout << "No players to display. ";
}
else
{
for (int i = 0; i < count;i++)
{
cout << i + 1 <<". " << football[i].name << endl;
cout << "Position: " << football[i].position << endl;
cout << "Touchdowns: " << football[i].touchdowns << endl;
cout << "Catches: " << football[i].catches << endl;
cout << "Passes: " << football[i].pass << endl;
cout << "Receiving Yards: " << football[i].receive << endl;
cout << "Rushing Yards: " << football[i].rush << endl;
}
}
}
void findandUpdate(string search, int count, player football[])
{
string name;
string position;
int touchdowns;
int catches;
int pass;
int receive;
int rush;
bool found = false;
for (int i = 0; i < count; i++)
{
if (search == football[i].name)
{
found = true;
cout << "Searched player is at index " << i + 1 << endl;
cout << "You may now update the player's name, player's position, number of touchdowns, number of catches,"
<< "number of passing yards, number of receiving yards, and the number of rushing yards \n";
cout << "Name: "; cin >> name;
cout << "Position: "; cin >> position;
cout << "Touchdowns: "; cin >> touchdowns;
cout << "Catches: "; cin >> catches;
cout << "Passes: "; cin >> pass;
cout << "Received: "; cin >> receive;
cout << "Rushed: "; cin >> rush;
football[i].name = name;
football[i].position = position;
football[i].touchdowns = touchdowns;
football[i].catches = catches;
football[i].pass = pass;
football[i].receive = receive;
football[i].rush = rush;
}
}
if (found == false)
{
cout << "No results.";
}
}
int main()
{
cout << "Press 1 to add a player.\nPress 2 to display players.\nPress 3 to find a player.\nPress 4 to update player information.\nPress 5 to save data.\n";
int x = 0;
cin >> x;
ifstream ifile;
player football[10];
ifile.open("footballplayers.txt");
int i = 0;
int count = 0;
while (i != -1)
{
switch (x)
{
case 1:
{
count = addData(ifile, count, football);
}
break;
case 2: display(count, football);
break;
case 3:
{
string name;
cout << "Enter football player name: ";
cin >> name;
findandUpdate(name,count, football);
}
break;
default: i = -1;
}
}
ifile.close();
string answer;
cout << "Save data? Type yes or no.";
cin >> answer;
if (answer == "yes")
{
ofstream ofile;
ofile.open("SavePlayerData.txt");
for (int i = 0; i < count; i++) {
ofile << football[i].name + " ";
ofile << football[i].name + " ";
ofile << football[i].position + " ";
ofile << football[i].touchdowns + " ";
ofile << football[i].catches + " ";
ofile << football[i].pass + " ";
ofile << football[i].receive + " ";
ofile << football[i].rush + " ";
ofile << "\n";
}
ofile.close();
}
}
Input file:
George RB 12 5 0 47 578
Brett QB 5 0 2017 0 44
Peyton WR 3 15 0 246 12
Logan WR 2 7 0 89 6
Nolan WR 1 2 3 0 0
John TE 5 17 0 402 0
Brandon QB 4 0 310 0 0
Dalton RB 1 2 43 5
Justin WR 1 10 0 441 0
Mason WR 0 2 0 12 0
your basic logic does not do as asked in the specs. First thing it should do is read the file, before asking for any input from a menu. You have tried to create a strange hybrid of reading the file and interactively adding a player (which is not part of the requirements)
So simplify and get it so that you read the whole file in a function called 'loadFile' and then print the whole thing out (like your option 2).
Get those things going first then add the menu to ask for modify, find and print
#include <h1>iostream <h2>
#include <h1>cmath<h2>// for + of months, days, and years
#include <h1>fstream<h2> //for in and output
#include <h1>cstdlib<h2>
#include <h1>string<h2>//for string type
using namespace std;
class Device {//Input and store Device Description and Serial Numbers
protected:
string serial_number;
string device_description;
public:
Device() {
serial_number = ("6DCMQ32");
device_description = ("TheDell");
}
Device(string s, string d) {
serial_number = s;
device_description = d;
}
};
class Test {
protected:
string Test_Description;
static int recent_month, recent_day, recent_year, new_month;
static int nmonth, next_month, next_day, next_year, max_day;
public:
static void getMonth() {//Calculates the next/new month
next_month = recent_month + nmonth;
new_month = next_month % 12;
if (next_month >= 12) {
cout << "The next Date: " << new_month << " / ";
}
else {
cout << "The next Date: " << next_month << " / ";
}
}
static void getDay() { //Calculates day of next month
if (new_month == 4 || new_month == 6 || new_month == 9 || new_month == 11) {
max_day = 30;
}
else if (new_month == 2) {
max_day = 29;
}
else {
max_day = 31;
}
if (recent_day > max_day) {
cout << max_day << " / ";
}
else {
cout << recent_day << " / ";
}
}
static void getYear() {//Calculates the year of the next number of months
next_year = recent_year + next_month;
if (next_year >= 12) {
cout << recent_year + (next_month / 12) << endl;
}
else {
cout << next_year << endl;
}
}
static void getDate() {
Test::getMonth(), Test::getDay(), Test::getYear();
}
};
int Test::recent_month, Test::recent_day, Test::recent_year,
Test::new_month;
int Test::nmonth, Test::next_month, Test::next_day, Test::next_year,
Test::max_day;
class Lab : public Device, public Test {//Class Lab is a Child of Class Test and Class Device
protected:
static int n;
public:
friend istream & operator>>(istream & cin, const Lab & lab) {
cout << "Enter Device Description and serial number: ";
getline(cin, lab.device_description);//This is where the error is
getline(cin, lab.serial_number);//This is where the error is
cout << "Enter Test Description: ";
getline(cin, lab.Test_Description);//This is where the error is
cout << "Enter number of months: ";
cin >> lab.nmonth;
cout << "Enter the most recent date(mm/dd/yyyy): ";
cin >> lab.recent_month >> lab.recent_day >> lab.recent_year;
return cin;
}
friend ostream & operator<<(ostream & cout, const Lab & lab) {
cout << lab.device_description << " ";
cout << lab.serial_number << endl;
cout << lab.Test_Description << endl;
getDate();
return cout;
}
static void getFile() {
cout << "Enter the number of devices: ";
cin >> n;
Lab *obj = new Lab[n];
if (obj == 0) {
cout << "Memory Error";
exit(1);
}
for (int i = 0; i<n; i++) {
cin >> obj[i];
}
ofstream myfile("Device.dat", ios::binary);
myfile.write((char *)obj, n * sizeof(Lab));
Lab *obj2 = new Lab[n];
ifstream file2("Device.dat", ios::binary);
if (obj2 == 0) {
cout << "Memory Error";
exit(1);
}
file2.read((char *)obj2, n * sizeof(Lab));
for (int i = 0; i < n; i++) {
cout << obj2[i];
cout << endl;
}
delete[] obj2;
}
void getSearch(){
}
};
void main() {
Lab L;
L.getFile();
system("pause");
}
//Error C2665 'std::getline': none of the 2 overloads could convert all
the argument types
/*
Purpose: is to enter the number of months for the next test date of device with input of serial number, Device Description, Test Description, recent date, and the number of months of two tests. At the end the program must be searched by having the user to input the serial number and the next date, if these two are valid everything in the device is listed out.
*/<
You shouldn't name your parameters like objects of the standard library (cin).
For an argument to be modifiable it must not be a reference to a constant entity.
Also, a std::istream bound operator<<() overload should not do output, but only extract the object required from the stream.
This question already has answers here:
Using fstream Object as a Function Parameter
(3 answers)
Closed 6 years ago.
#include <bits/stdc++.h>
using namespace std;
class contact {
private:
vector< pair<string, int> > contact_info;
public:
void add_contact(string contact_name, int contact_number) {
contact_info.push_back(make_pair(contact_name, contact_number));
sort(contact_info.begin(),contact_info.end());
}
void edit_contact(string contact_name) {
int found_at;
for (unsigned int i =0; i < contact_info.size(); i++) {
if (contact_info[i].first == contact_name) {
found_at = i;
}
}
if (contact_info[found_at +1].first == contact_name) {
int choice;
int counter = found_at;
int index = 1;
while (contact_info[counter].first == contact_name) {
cout << index << ". " << contact_info[counter].first << " " << contact_info[counter].second;
counter++;
index++;
}
cout << "Choose any please: ";
cin >> choice;
found_at = found_at - (choice - 1);
}
cout << "Enter the new number: ";
cin >> contact_info[found_at].second;
}
void show_all() {
for (unsigned int i =0; i < contact_info.size(); i++) {
cout << contact_info[i].first << " " << contact_info[i].second << endl;
}
}
void delete_contact(string contact_name) {
int found_at;
for (unsigned int i =0; i < contact_info.size(); i++) {
if (contact_info[i].first == contact_name) {
found_at = i;
}
}
if (contact_info[found_at +1].first == contact_name) {
int choice;
int counter = found_at;
int index = 1;
while (contact_info[counter].first == contact_name) {
cout << index << ". " << contact_info[counter].first << " " << contact_info[counter].second;
counter++;
index++;
}
cout << "Choose any please: ";
cin >> choice;
found_at = found_at - (choice - 1);
}
contact_info.erase(contact_info.begin()+found_at);
}
void writeFile(ofstream contact_file) {
for (unsigned int i =0; i < contact_info.size(); i++) {
contact_file << contact_info[i].first << " " << contact_info[i].second << endl;
}
}
void readFile(ifstream contact_file) {
string input;
while (!contact_file.eof()) {
contact_file >> input;
size_t pos = input.find(" ");
string name = input.substr(0,pos);
string number_str = input.substr(pos);
int number = stoi(number_str) ;
contact_info.push_back(make_pair(name,number));
}
}
};
int main()
{
int choice;
ifstream contacts_file_read;
contacts_file_read.open("contacts.txt");
ofstream contacts_file_write;
contacts_file_write.open("contacts.txt");
bool in_prog = true;
contact contacts;
string name;
int number;
while (in_prog) {
cout << "1. Add contacts" << endl
<< "2. Edit contact" << endl
<< "3. Delete contact" << endl
<< "4. Show all" << endl
<< "5. exit" << endl;
cout << "Your choice: ";
cin >> choice;
contacts.readFile(contacts_file_read);
if (choice == 1) {
cout << "Enter name & number separated by a space: ";
cin >> name >> number;
contacts.add_contact(name, number);
} else if (choice == 2) {
cout << "Enter name of contacts to be edited: ";
cin >> name;
contacts.edit_contact(name);
} else if (choice == 3) {
cout << "Enter name of contact to be deleted: ";
cin >> name;
contacts.delete_contact(name);
} else if (choice == 4) {
contacts.show_all();
} else if(choice == 5) {
contacts.writeFile(contacts_file_write);
} else {
cout << "Wrong choice" << endl;
}
}
return 0;
}
So, I was asked in my programming class to make a phone book application in C++ using only objects, so this is my attempt at it.
All functions are good, I did recompile the program after finishing each function at it gave me 0 errors, however whenever I try to call writeFile or readFile function that were previously working fine, now the compiler gave me an error of "error: use of deleted functions... "
I don't know what are deleted functions and why only functions that take file objects as an argument are treated as such.
Can anyone please help?
Thanks.
Objects of type std::ifstream are not copyable -- indeed, the object represents the unique handle of an open file, and it would be difficult to conceptualize what it would mean to copy such unique responsibility.
Indeed, this inability to copy an object is encoded by making the copy constructor deleted, which causes the error that you see when you do attempt to copy it.
Your code should pass the original ifstream, not a copy (by taking a reference parameter):
void readFile(ifstream & contact_file)
// ^^^^^^^^^^
I am currently working on the assignment where I need to iterate through some student records. Each record has reg. number, name, and 0 to multiple module names with marks respectively.
I have a Student class and a Main class.
In the main class there's a function to iterate through a vector of Students and print the average grade.
Function to print average grades as well as names.
void aboveGiven(vector<Student> &students, float given) {
vector<Student>::iterator it;
for(it = students.begin(); it != students.end(); it++) {
if(it -> getAverageMark() >= given) {
cout << it->getName() << " " << setprecision(2) << it->getAverageMark() << endl;
}
}
}
Function to calculate average grade. "Given" parameter is the input used to define above what average to display the records. (in this case it is 70 meaning all the records with average above 70 have to be printed)
float Student::getAverageMark() const
{
if (marks.size() == 0)
return 0;
int count;
float sum;
map<string, float>::const_iterator it;
for (it = marks.begin(); it != marks.end(); ++it, ++count) {
sum += it->second;
}
return sum / count;
}
The massive problem I have is weird behaviour of cout where it prints nothing if I pass 60 or above as a "Given" parameter.
However the following code:
void aboveGiven(vector<Student> &students, float given) {
vector<Student>::iterator it;
for(it = students.begin(); it != students.end(); it++) {
cout << "a" << endl;
if(it -> getAverageMark() >= given) {
cout << it->getName() << " " << setprecision(2) << it->getAverageMark() << endl;
}
}
}
with only difference of line cout << "a" << endl;gives me following output:
a
a
a
Lisa Simpson 88.03
a
Homer Simpson 99.90
a
a
Wayne Rooney 75.45
a
a
a
a
Where 'a' corresponds to all the records with average grade below 70 and, as we can see all the records with average grade above 70 are now printed well.
Sometimes, when using different parameters for cout, only some of the outputs would be actually displayed but not all.
I am new to C++ and still am very confused with references and pointers, so I suspect there might be a problem with them. Otherwise could this be an issue with IDE ( I am using CLion which supports C++11).
I am sorry if this is not informative enough, have never posted anything here before. If you need any additional information please feel free to ask, I will post it.
classes just in case:
Student.cpp
using namespace std;
#include "Student.h"
#include <iostream>
Student::Student(const string& name, int regNo)
: Person(name)
{
this->name = name;
this->regNo = regNo;
this->marks = marks;
}
int Student::getRegNo() const
{
return regNo;
}
void Student::addMark(const string& module, float mark)
{
marks[module] = mark;
}
float Student::getMark(const string& module) throw(NoMarkException)
{
if (marks.find(module) == marks.end()) {
throw NoMarkException();
}
return marks[module];
}
float Student::getAverageMark() const
{
if (marks.size() == 0)
return 0;
int count;
float sum;
map<string, float>::const_iterator it;
for (it = marks.begin(); it != marks.end(); ++it, ++count) {
sum += it->second;
}
cout << fixed;
return sum / count;
}
And main: (at the moment it is really bad styled, sorry)
using namespace std;
#include <iostream>
#include <fstream>
#include <sstream>
#include "Student.h"
#include <vector>
#include <iomanip>
void aboveGiven(vector<Student>& students, float given)
{
vector<Student>::iterator it;
for (it = students.begin(); it != students.end(); it++) {
cout << "a" << endl;
if (it->getAverageMark() >= given) {
cout << it->getName() << " " << setprecision(2) << it - > getAverageMark() << endl;
}
}
}
int main()
{
char studentFileName[30];
char marksFileName[30];
vector<Student> students;
cout << "Enter the name of a file with Students: " << endl;
cin >> studentFileName;
ifstream studentFile;
string line;
studentFile.open(studentFileName, ios::in);
if (studentFile.is_open()) {
while (getline(studentFile, line)) {
istringstream iss(line);
int regn;
string firstName, lastName;
iss >> regn >> firstName >> lastName;
students.push_back(Student(firstName + " " + lastName, regn));
}
studentFile.close();
}
else {
cout << "Failed to open: " << studentFileName << endl;
}
cout << "Enter the name of a file with Marks: " << endl;
cin >> marksFileName;
ifstream marksFile;
string ln;
marksFile.open(marksFileName, ios::in);
if (marksFile.is_open()) {
while (getline(marksFile, ln)) {
int regn;
string module;
float mark;
bool studentFound = false;
istringstream iss(ln);
iss >> regn >> module >> mark;
for (auto& student : students) {
if (student.getRegNo() == regn) {
student.addMark(module, mark);
studentFound = true;
}
}
if (!studentFound) {
cout << "Student with Registration Number " << regn << was not found." << endl;
}
}
marksFile.close();
}
else {
cout << "Failed to open: " << marksFileName << endl;
}
for (auto& student : students) {
map<string, float> tempMap = student.getMarks();
map<string, float>::iterator it;
cout << setw(20) << student.getName() << ": ";
if (tempMap.size() == 0) {
cout << "N/A";
}
else {
for (it = tempMap.begin(); it != tempMap.end(); it++) {
cout << setw(5) << it->first << '(' << it->second << "); ";
}
}
cout << endl;
}
aboveGiven(students, 70);
}
Thanks in advance for your help!
You didn't initialize int sum and int count in Student::getAverageMark. Then no one knows what could they be. They must be int sum = 0; and int count = 0;
I have been having some trouble on my code for my final project. I have looked everwhere and I am having a hard time so I thought I would ask on here. I need to make sure that when all the names are listed in this phonebook that they will come out in alphabetical order but as of yet I am unsure how to do that. Here is the program that i currently have! Thank you!
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
struct Contact {
string name, number, notes;
};
Contact contactList[100];
int rec_num = 0;
int num_entries;
string toUpper (string S) {
for (int i= 0; i < S.length(); i++)
S[i] = toupper(S[i]);
return S;
}
void ReadFile () {
string S;
fstream input("PhoneData.txt");
while (!input.eof() && !input.fail()){
input >> contactList[rec_num].name >> contactList[rec_num].number;
getline(input, S);
contactList[rec_num].notes = S;
rec_num++;
}
cout << "Book read." << endl;
num_entries = rec_num;
input.close();
return;
}
// stores phonebook for future runs of the program
void StoreFile () {
fstream F ("PhoneData.txt");
rec_num = 0;
while (rec_num < num_entries){
F << contactList[rec_num].name << " " << contactList[rec_num].number << " " << contactList[rec_num].notes << " " << endl;
rec_num++;
}
cout << "Phonebook stored." << endl;
return;
}
// adds contact
void add_name(string name, string number, string notes){
contactList[num_entries].name = name;
contactList[num_entries].number = number;
contactList[num_entries].notes = notes;
num_entries++;
return;
}
// finds contact
void retrieve_name(string name){
for (int i = 0; i < num_entries; i++){
if (toUpper(contactList[i].name) == toUpper(name)) {
cout << "Phone Number: " << contactList[i].number << endl << "Notes: " << contactList[i].notes << endl;
return;
}
}
cout << "Name not found" << endl;
return;
}
// updates contact info
void update_name(string name){
string new_number;
string new_notes;
cout<<"New Phone Number"<<endl;
cin>> new_number;
cout<<"New Notes"<<endl;
cin>> new_notes;
for (int i = 0; i < num_entries; i++){
if (toUpper(contactList[i].name) == toUpper(name)) {
contactList[i].number = new_number;
contactList[i].notes = new_notes;
return;
}
}
}
// deletes contact
void delete_name(string name){
int INDEX=0;
for (int i = 0; i < num_entries; i++){
if (toUpper(contactList[i].name) == toUpper(name)) {
INDEX=i;
for ( int j=INDEX; j < num_entries; j++ ){
contactList[j].name = contactList[j+1].name;
contactList[j].number = contactList[j+1].number;
contactList[j].notes = contactList[j+1].notes;
}
}
}
return;
}
void listAllContacts() {
int i = 0;
while (i < num_entries) {
cout << "-- " << contactList[i].name << " " << contactList[i].number << endl << "-- " << contactList[i].notes << endl << endl;
i++;
}
}
int main(){
string name, number, notes;
string FileName;
char command;
FileName = "PhoneData.txt";
ReadFile ();
cout << "Use \"e\" for enter, \"f\" for find, \"l\" for list, \"d\" for delete, \"u\" for update, \"s\" for send message, \"q\" to quit." << endl << "Command: ";
cin >> command;
while (command != 'q'){
switch (command){
case 'e': cin >> name; cout << "Enter Number: ";
cin >> number; cout << "Enter Notes: ";
cin.ignore(); getline(cin, notes);
add_name(name, number, notes); break;
case 'f': cin >> name; retrieve_name(name); break;
case 'l':
listAllContacts(); break;
case 'u': cin>> name; update_name (name);break;
case 'd' : cin>> name; delete_name (name); break;
}
cout << "\nCommand: "; cin >> command;
}
StoreFile();
cout << "All set !";
return 0;
}
Given
Contact contactList[100];
int num_entries;
you can use std::sort to sort the list of contacts. std::sort has two forms. In the first form, you can use:
std::sort(contanctList, contactList+num_entries);
if you define operator< for Contact objects.
In the second form, you can use:
std::sort(contanctList, contactList+num_entries, myCompare);
if you define myCompare to be callable object that can compare two Contact objects.
To use the first form, change Contact to:
struct Contact {
string name, number, notes;
bool operator<(Contact const& rhs) const
{
return (this->name < rhs.name);
}
};
If you want to the comparison of names to be case insensitive, convert both names to either uppercase or lowercase and them compare them.