I am working on a program through Xcode, it is supposed to read a file and perform various functions:
displayMenu,
doDisplay,
doView,
doAdd,
doEdit,
doDelete.
I have gotten it all to work except the do edit and do delete functions, and I can't find anything online that helps with my particular situation.
The user is supposed to pick the course they want to edit, and be able to edit the term, year, start date, end date, etc.
Thank you in advance.
Here is my code attached.
Here are instructions if you are curious:
Course Menu
=====================
d - Display list of courses
v - View course details
a - Add a course
e - Edit a course
d - Delete a course
x - Exit program
Requirements
Given a comma-delimited text file named courses.csv Download
courses.csv(click to download) that stores the starting data for the
program.
A course is an organized presentation about a particular subject that includes Term, Year, Start Date, End Date, Course Name, Class ID, Section, Meeting Days, Location (online, hybrid, or on-campus), Meeting Information, Instructor, Units.
For the view, edit, and delete commands, display an error message if
the user selects an invalid course.
Define a data structure to store the data for each course.
When you start the program, it should read the contacts from the
comma-delimited text file and store them in a vector of courses.
When reading data from the text file, you can read the line and
separate the field by an all text up to the next comma (ex. getline()
function).
When you add, edit or delete a contact, the change should be saved to
the text file immediately. That way, no changes are lost, even if the
program crashes later.
For demonstration, you need to be able to view/add/edit/delete at
least 3 courses listed
Here is my code: https://pastebin.com/HkEE9HBD
////myApp.cpp
#include <iostream>
#include <string>
#include <vector>
#include <iomanip>
#include "course.h"
#include "utils.h"
using namespace std;
char menu();
int main() {
vector<courseType> list;
readData(list);
char ch = 'x';
do {
cout << endl;
ch = menu();
switch (ch) {
case 'l':
// function handler
doDisplay(list);
break;
case 'v':
doView(list);
break;
case 'a':
doAdd(list);
break;
case 'e':
doEdit(list);
break;
case 'd':
doDelete(list);
break;
default:
cout << "Please enter valid choice" << endl;
}
} while (ch != 'x');
cout << "Exit the program" << endl;
return 0; // exit the program successfully
}
/**
* Display application menu
*/
char menu() {
cout << "Course Menu" << endl;
cout << "=====================" << endl;
cout << "l - Display list of courses" << endl;
cout << "v - View course details" << endl;
cout << "a - Add a course" << endl;
cout << "e - Edit a course" << endl;
cout << "d - Delete a course" << endl;
cout << "x - Exit program" << endl << endl;
cout << "Enter choice: ";
char ch;
cin >> ch;
cout << endl;
return ch;
}
//courseImp.cpp
#include <string>
#include "course.h"
#include <iostream>
using namespace std;
courseType::courseType() {
term = "";
year = 0.0;
startDate = "";
endDate = "";
courseName = "";
section = "";
classID = 0.0;
meetingDays = "";
location = "";
meetingInfo = "";
instructor = "";
units = 0.0;
}
courseType::~courseType() {
}
//List of Acessor and Getter Methods For Each Variable
void courseType::setTerm(string term) {
this ->term = term;;
}
string courseType::getTerm() {
return term;
}
void courseType::setYear(string temp) {
this ->temp = temp;
}
string courseType::getYear() {
return temp;
}
void courseType::setStart(string startDate) {
this ->startDate = startDate;
}
string courseType::getStart() {
return startDate;
}
void courseType::setEnd(string endDate) {
this ->endDate = endDate;
}
string courseType::getEnd() {
return endDate;
}
void courseType::setName(string courseName) {
this ->courseName = courseName;
}
string courseType::getName() {
return courseName;
}
void courseType::setSection(string section) {
this ->section = section;
}
string courseType::getSection() {
return section;
}
void courseType::setID(string tempC) {
this->tempC = tempC;
}
string courseType::getID() {
return tempC;
}
void courseType::setDays(string meetingDays) {
this ->meetingDays = meetingDays;;
}
string courseType::getDays() {
return meetingDays;
}
void courseType::setLocation(string location) {
this ->location = location;
}
string courseType::getLocation() {
return location;
}
void courseType::setInfo(string meetingInfo) {
this ->meetingInfo = meetingInfo;
}
string courseType::getInfo() {
return meetingInfo;
}
void courseType::setInstructor(string instructor) {
this ->instructor = instructor;
}
string courseType::getInstructor() {
return instructor;
}
void courseType::setUnits(string tempU) {
this ->tempU = tempU;
}
string courseType::getUnits() {
return tempU;
}
//utils.cpp
#include <iostream>
#include <iomanip>
#include "utils.h"
#include "course.h"
#include <cstdlib>
#include <iostream>
#include <utility>
#include <string>
#include <fstream>
#include <vector>
#include <iterator>
#include <algorithm>
using namespace std;
//Function Dislays list of Courses
void doDisplay(vector<courseType>& list) {
cout << left << setw(10) << "Course List" << endl;
cout << "==============================" << endl;
for(int i = 0; i < list.size(); i++){
cout << left << setw(10) << list[i].getName() << "" << endl << endl;
}
}
//Function views individual course
void doView(vector<courseType>& list) {
int chv = 0;
for(int i = 0; i < list.size(); i++){
cout << i+1 << ". " << list[i].getName() << "" << endl << endl;
}
cout << "Please choose a course you want to view: ";
cin >> chv;
cout << endl;
if(chv<list.size()+1)
{
cout << left << setw(10) << "Term" << setw(10) << "Year"
<< setw(15) << "Start Date" << setw(15) << "End Date"
<< setw(35) <<"Course Name" << setw(15) << "Section"
<< setw(12) << "Class ID" << setw(17) << "Meeting Days"
<< setw(15) << "Location" << setw(20) << "Meeting Info"
<< setw(15) << "Instructor" << "Units" << endl;
cout << "=============================================================================================";
cout << "=============================================================================================" << endl;
chv=chv-1;
cout << left << setw(10) << list[chv].getTerm() << "" << setw(10) << list[chv].getYear() <<
"" << setw(15) << list[chv].getStart() << "" << setw(15) << list[chv].getEnd() << "" <<
setw(35) << list[chv].getName() << "" << setw(15) << list[chv].getSection() << "" <<
setw(15) << list[chv].getID() << "" << setw(15) << list[chv].getDays() << "" <<
setw(17) << list[chv].getLocation() << "" << setw(20) << list[chv].getInfo() << "" <<
setw(15) << list[chv].getInstructor() << "" << setw(10) << list[chv].getUnits() << "" << endl;
}
}
//Function Adds Courses
void doAdd(vector<courseType>& list) {
char choice;
char delim = ',';
string term = "";
float year = 0.0;
string start = "";
string end = "";
string name = " ";
string section = "";
float id = 0.0;
string days = "";
string location = "";
string info = "";
string instructor = "";
float units = 0.0;
ofstream outMyStream (FILE_NAME, ios::app);
do {
cout << "Enter term: " ;
cin.ignore();
getline(cin, term);
cout << "Enter year: ";
cin >> year;
cin.ignore();
cout << "Enter start date: ";
getline(cin, start);
cout << "Enter end date: ";
getline(cin, end);
cout << "Enter course name: ";
getline(cin, name);
cout << "Enter course section: ";
getline(cin, section);
cout << "Enter course ID: ";
cin >> id;
cin.ignore();
cout << "Enter meeting Days : ";
getline(cin, days);
cout << "Enter meeting location: ";
getline(cin, location);
cout << "Enter meeting information: ";
getline(cin, info);
cout << "Enter instructor name: ";
getline(cin, instructor);
cout << "Enter units: ";
cin >> units;
cin.ignore();
outMyStream << term << delim << year << delim << start << delim << end << delim << name << delim << section << delim
<< id << delim << days << delim << location << delim << info << delim << instructor << delim << units << endl;
cout << "\nEnter another Record? (Y/N) ";
cin >> choice;
if (choice != 'Y' and choice != 'y' and choice != 'N' and choice != 'n') // if needed add input
cout << choice << " is not a valid option. Try agian" << endl;
}while (choice != 'N' && choice != 'n');
{
outMyStream.close();
}
}
//Function Edits Courses
void doEdit(vector<courseType>& list) {
}
//Function Deletes Courses
void doDelete(vector<courseType>& list) {
}
//Function Reads Data from "courses.csv"
void readData(vector<courseType>& list) {
ifstream inFile;
fstream fin;
inFile.open(FILE_NAME);
string line;
while (getline(inFile, line)) {
string term;
float year;
string startDate;
string endDate;
string courseName;
string section;
float classID;
string meetingDays;
string location;
string meetingInfo;
string instructor;
float units;
string temp;
string tempU;
string tempC;
stringstream ss(line);
getline(ss, term, ',');
getline(ss, temp, ',');
year = atoi(temp.c_str());
getline(ss, startDate, ',');
getline(ss, endDate, ',');
getline(ss, courseName, ',');
getline(ss, section, ',');
getline(ss,tempC,',');
classID = atoi(tempC.c_str());
getline(ss, meetingDays, ',');
getline(ss, location, ',');
getline(ss, meetingInfo, ',');
getline(ss, instructor, ',');
getline(ss,tempU,',');
units = atoi(tempU.c_str());
courseType c;
c.setTerm(term);
c.setYear(temp);
c.setStart(startDate);
c.setEnd(endDate);
c.setName(courseName);
c.setSection(section);
c.setID(tempC);
c.setDays(meetingDays);
c.setLocation(location);
c.setInfo(meetingInfo);
c.setInstructor(instructor);
c.setUnits(tempU);
list.push_back(c);
}
inFile.close();
}
//course.h
#pragma once
#include <string>
#include <sstream>
using namespace std;
class courseType {
public:
// mutator methods - set
void setTerm(string term);
void setYear(string temp);
void setStart(string startDate);
void setEnd(string endDate);
void setName(string courseName);
void setSection(string section);
void setID(string tempC);
void setDays(string meetingDays);
void setLocation(string location);
void setInstructor(string instructor);
void setInfo(string meetingInfo);
void setUnits(string tempU);
// ...
// accessor methods - get
string getTerm();
string getYear();
string getStart();
string getEnd();
string getName();
string getSection();
string getID();
string getDays();
string getLocation();
string getInstructor();
string getInfo();
string getUnits();
// ...
// Other member methods
// ...
courseType();
~courseType();
protected:
// tbd
private:
// data structures
string term;
float year;
string startDate;
string endDate;
string courseName;
string section;
float classID;
string meetingDays;
string location;
string meetingInfo;
string instructor;
float units;
string temp;
string tempU;
string tempC;
};
//utils.h
#pragma once
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
#include "course.h"
using namespace std;
const string FILE_NAME = "courses.csv";
// Prototype functions...
void doDisplay(vector<courseType>& list);
void doView(vector<courseType>& list);
void doAdd(vector<courseType>& list);
void doEdit(vector<courseType>& list);
void doDelete(vector<courseType>& list);
void readData(vector<courseType>& list);
//courses.csv
Spring,2022,1/24/2022,5/20/2022,Discrete Structures,CS-113-02,085689,T TH,On-Campus,Newark,Pham,3
Spring,2022,1/24/2022,5/20/2022,Programming W/ Data Structures,CS-124-02,084371,M W,On-Campus,Zoom,Pham,3
Spring,2022,1/24/2022,5/20/2022,Programming W/ Data Structures,CS-124-03,085698,T TH,Online,Newark,Pham,3
Spring,2022,1/24/2022,5/20/2022,JavaScript for Web Development,CS-175-01,084377,M,Online,Zoom,J. Pham,4
Spring,2022,1/24/2022,5/20/2022,Beginner Java,CS-125-05,089434,TH,Online,Zoom,Gao,3
Ah, college professors... Store things in csv files but act like it's a database.
What I would do is design a set of classes that mirror your data. So you'd have a class called Course (for instance). And you'd have another called Curriculum, perhaps, and it would store a std::vector of Courses.
You would then need a readFromCSV and writeToCSV pair of methods. You would want more methods for the various actions you have to perform, and any methods that modify data should then call writeToCSV automatically.
Does that make sense?
You can build it by first just writing the read and write methods and just make sure your output file looks identical to your input file.
Then start implementing the data update methods, one at a time.
Not too bad.
The code :
class DataBase {
private:
int age, stuNumNew;
string stuName, command;
string ver = "Alpha";
float stuNum = 1;
public:
void Start() {
cout << "Welcome back to Sudent DataBase <ver " << ver << ">." << endl;
cout << "Type 'Add' for add a student.";
cin >> command;
if (command == "Add") {
Add();
}
else if (command == "Search") {
cout << "Student number: ";
cin >> stuNumNew; //Get input from user
cout << "Name: " << stuName[stuNumNew] << endl << "Age: " << age[&stuNumNew] << endl;
Start();
}
}
void Add() {
cout << "Name: ";
**cin >> stuName[stuNum] * *; //get the name
cout << "Age: ";
cin >> age[stuNum]; //get the age
cout << "Student Number: " << stuNum;
stuNum = stuNum++;
stuNumNew = stuNum;
Start();
}
};
Vectors allow you to create variable size arrays
The issue you're having is caused by using a fixed size variable. What you need in this case is a vector because what you are trying to do is assign names and numbers to arrays that are of variable sizes so that you can add new students in your program.
Vectors allow you to do just that.
Here is the modified code:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class DataBase {
private:
int searchInput;
/* declare a vector of type int to contain your students' ages */
vector<int> studentAges;
/* declare a vector of type std::string to contain your students' names */
vector<string> studentNames;
string command;
string ver = "Alpha";
/* stuNum is removed because vectors keep track of their own sizes */
public:
void Start() {
cout << "Welcome back to Student DataBase <ver " << ver << ">." << endl;
cout << "Type 'Add' to add a new student or type 'Search' to search the database of students." << endl << " > ";
cin >> command;
if (command == "Add") {
Add();
} else if (command == "Search") {
/* You may want to build in a conditional that checks if there are any students yet. */
cout << "Student number: ";
cin >> searchInput;
if (searchInput < studentNames.size()) {
/* Make sure that the users input (the number) is actually a student's id number
* otherwise reject their input to keep the program from crashing or having undefined behavior.
*/
cout << "Name: " << studentNames[searchInput] << endl << "Age: " << studentAges[searchInput] << endl;
} else {
cout << "Student number invalid" << endl;
}
} else {
/* Tell them if their input is invalid */
cout << "Invalid option." << endl;
}
Start();
}
void Add() {
/* Append new positions for input */
studentNames.push_back("");
studentAges.push_back(0);
cout << "Name: ";
cin >> studentNames.back();
cout << "Age: ";
cin >> studentAges.back();
/* The student number is the newest index of the vector */
cout << "Student Number: " << studentNames.size() - 1 << endl;
}
};
int main() {
DataBase d;
d.Start();
}
You can also combine your variables studentNames and studentAges into a students vector if you create a class (or struct) that keeps both values together:
class Student {
public:
Student(string name, int age) {
this->age = age;
this->name = name;
}
string name;
int age;
};
Then you can use it with vector:
vector<Student> students;
NOTE:
You may want to add some input protecting because if you enter a string where it wants a number it breaks the program.
I can easily create a void function to output something like a header, but I cannot get a program to read a user's input and then output it to them.
ie. Have a program say "Please enter your first name" and then output "You entered: (what they put)"
An example of what I have:
#include<iostream>
#include<conio.h>
#include<iomanip>
#include<fstream>
using namespace std;
void namefn()//namefn prototype
int main(){
string firstName,lastName;
return 0;
}
void namefn(string firstName, string lastName){
cout<<"please enter your first and last name "<<endl;
}
Use cin to read, is in iostream.
i.e.
cin >> firstName;
cout << "enter your first and last name:";
cin >> firstName >> lastName;
cout << firstName << " " << lastName;
if you want the program to display the first name and last name separately then this:
cout << "enter you first name:";
cin >> firstName;
cout << firstName << endl;
cout << "Enter your last name:";
cin >> lastName;
cout << lastName << endl;
Try this:
#include <iostream>
#include <string>
void displayFirstAndLast(const std::string& firstName, const std::string& lastName)
{
std::cout << "You are " << firstName << " " << lastName << std::endl;
}
int main(){
std::string firstName;
std::string lastName;
std::cout << "Please enter your first and last name " << std::endl;
std::cin >> firstName >> lastName;
displayFirstAndLast(firstName, lastName);
return 0;
}
I think, that you want something like this.
Or with something like "header"
#include <iostream>
#include <string>
void displayFirstAndLast(const std::string& firstName, const std::string& lastName);
int main(){
std::string firstName;
std::string lastName;
std::cout << "Please enter your first and last name " << std::endl;
std::cin >> firstName >> lastName;
displayFirstAndLast(firstName, lastName);
return 0;
}
void displayFirstAndLast(const std::string& firstName, const std::string& lastName)
{
std::cout << "You are " << firstName << " " << lastName << std::endl;
}
Basically My Program Goal is that i have a file containing 4 telephone numbers
it would Look Like this
Harry Keeling (555)123-4567
Frank James (555)123-8901
Arthur Paul (555)987-4567
Todd Shurn (555)987-8901
What my program is doing right now is prompting the user for the name and last name and iterates through the file to see if their is a match if their is a match the phone number is saved in the variable phone number if their isnt a match the program outputs error right now my program is doing what is susposed to do but after each match is found the program is susposed to prompt do you want to continue looking up numbers y or n if it is a yes it is susposed to loop through the file again but basically my program isnt working and i have no idea why my code
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void lookup_name(ifstream&, string&); // prototype
int main()
{
ifstream myfile;
string phonenumber;
string choice;
lookup_name(myfile, phonenumber);
if (phonenumber == " ") {
cout << "Error" << endl;
}
else {
cout << "The Telephone Number you Requested is" << phonenumber << endl;
cout << "Do you Want to look up another name in the directory?" << " " << "<Y/N" << endl;
cin >> choice;
if (choice == "Y")
lookup_name(myfile, phonenumber);
}
}
void lookup_name(ifstream& myfile, string& phonenumber)
{
string fname;
string lname;
string name1, name2, dummy, choice;
myfile.open("infile.txt");
cout << "What is your first name" << endl;
cin >> fname;
cout << "What is your last name" << endl;
cin >> lname;
for (int i = 0; i < 4; i++) {
myfile >> name1 >> name2;
if (fname + lname == name1 + name2) {
myfile >> phonenumber;
myfile.close();
if (choice == "Y")
{
continue;
}
else {
myfile >> dummy;
}
}
}
}
You need to add a loop inside of main() itself to prompt the user to continue, and you need to fix the mistakes in your lookup_name() function.
Try something more like this instead:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <limits>
using namespace std;
bool lookup_name(istream&, const string&, string&); // prototype
int main()
{
ifstream myfile("infile.txt");
string name, phonenumber, choice;
do
{
cout << "What is the name? ";
getline(cin, name);
if (!lookup_name(myfile, name, phonenumber)) {
cout << "Error" << endl;
}
else {
cout << "The Telephone Number you Requested is '" << phonenumber << "'" << endl;
}
cout << "Do you want to look up another name in the directory (Y/N)? ";
cin >> choice;
cin.ignore(numeric_limits<streamsize_t>::max(), '\n');
if ((choice != "Y") && (choice != "y"))
break;
myfile.seekg(0);
}
while (true);
return 0;
}
bool lookup_name(istream& myfile, const string& name, string& phonenumber)
{
string line, fname, lname;
while (getline(myfile, line))
{
istringstream iss(line);
if (iss >> fname1 >> lname)
{
if (name == (fname + " " + lname))
return getline(iss, phonenumber);
}
}
return false;
}
I'm writing a simple program to enter student records and store them in a coma delimited file. Everything looks good but when I run the program I get an error:
Error 1 error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>' c:\program files\microsoft visual studio 10.0\vc\include\fstream 1116 1 project1
Here's the code:
#include <cstring>
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;
void closeOrNewRecordMenu(string enterAnotherRecord)
{
if (enterAnotherRecord == "Q" && enterAnotherRecord == "q")
{
exit(0);
}
}
void newStudentRecord(double studentNumber, string firstName, string lastName, string campus, string course1, string course2, string course3, string seniorPracticum, ofstream writeToRecordsFile)
{
int campusChoice;
do {
cout << "Student's six digit number: (Numeric only)";
cin >> studentNumber;
cin.ignore();
}
while (studentNumber < 100000 && studentNumber > 999999);
cout << "Student's first name: " << "\n";
cin >> firstName;
cin.ignore();
cout << "Student's last name: " << "\n";
cin >> lastName;
cin.ignore();
while (campusChoice < 1 || campusChoice > 3)
cout << "Which campus will " << firstName << " " << lastName << " be attending class at: " << "\n";
cout << "For the North campus enter 1" << "\n";
cout << "For the South campus enter 2" << "\n";
cout << "For the Seaside campus enter 3" << "\n";
cin >> campusChoice;
cin.ignore();
if (campusChoice == 1)
{
campus = "North Campus";
}
else if (campusChoice == 2)
{
campus = "South Campus";
}
else if (campusChoice == 3)
{
campus = "Seaside Campus";
}
else {
cout << "Please enter a valid choice." << "\n" << "\n";
}
cout << "Student's first course: " << "\n";
getline (cin, course1);
cin.ignore();
cout << "Student's second course: " << "\n";
getline (cin, course2);
cin.ignore();
cout << "Student's third course: " << "\n";
getline (cin, course3);
cin.ignore();
do {
cout << "Is " << firstName << " " << lastName << " a senior this year? Please enter \"Y\" for yes and \"N\" for no." << "\n";
cin >> seniorPracticum;
cin.ignore();
} while (seniorPracticum != "y" && seniorPracticum != "Y" && seniorPracticum != "n" && seniorPracticum != "N");
writeToRecordsFile << studentNumber << "," << firstName << "," << lastName << "," << campus << "," << course1 << "," << course2 << "," << course3 << "," << seniorPracticum << "\n";
cout << "The student record for " << firstName << " " << lastName << " has been saved." << "\n" << "\n";
}
int main()
{
cout << "Hello there! Welcome to the student record manager. From here you can enter new student information and save it to a file!!!! (More exciting to the developer than the user)." << "\n" << "\n";
string enterAnotherRecord;
ofstream writeToRecordsFile;
writeToRecordsFile.open("cop2224_proj1.txt");
while (enterAnotherRecord != "Q" && enterAnotherRecord != "q") {
cout << "Press \"N\" to create a new student record or press \"Q\" to quit." << "\n" << "\n";
cin >> enterAnotherRecord;
closeOrNewRecordMenu(enterAnotherRecord);
string firstName, lastName, seniorPracticum, campus, course1, course2, course3;
double studentNumber;
newStudentRecord(studentNumber, firstName, lastName, campus, course1, course2, course3, seniorPracticum, writeToRecordsFile);
}
writeToRecordsFile.close();
}
Streams are not copyable, and even if they were, you wouldn't want to do so here – pass by reference instead. Change your newStudentRecord signature to:
void newStudentRecord(double studentNumber, string firstName, string lastName, string campus, string course1, string course2, string course3, string seniorPracticum, ofstream& writeToRecordsFile);
That being said, why are you passing in all those arguments when you don't care about their initial values and you don't use them as output parameters? Simplify your signature to the following:
void newStudentRecord(ofstream& writeToRecordsFile);
and declare the other arguments as local variables inside of newStudentRecord.
As an aside, you're reading campusChoice before initializing it, which will yield undefined behavior.