Better way to loop through user input - c++

So I've been working on a little program that asks the user for the name/hours studying for a given topic, then does some calculations and displays the results back. Right now, to get the input for, say, 4 topics, I'm doing it this way:
#include <iostream>
using namespace std;
int main()
{
string topic1 = "";
string topic2 = "";
string topic3 = "";
string topic4 = "";
/* could have more topics here */
double hoursStudying1 = 0;
double hoursStudying2 = 0;
double hoursStudying3 = 0;
double hoursStudying4 = 0;
cout << "Topic name: ";
getline(cin, topic1);
cout << "Time studying for " << topic1 << ": ";
cin >> hoursStudying1;
cin.ignore();
cout << "Topic name: ";
getline(cin, topic2);
cout << "Time studying for " << topic2 << ": ";
cin >> hoursStudying2;
cin.ignore();
cout << "Topic name: ";
getline(cin, topic3);
cout << "Time studying for " << topic3 << ": ";
cin >> hoursStudying3;
cin.ignore();
/* calculate stuff here */
/* display the results */
cout << "For " << topic1 << " you spent " << hoursStudying1 << " hours studying" << endl;
/* etc */
return 0;
}
I'm a beginner, but I know there has to be a more efficient way to do this :(. How could I use, for example, a do...while loop or even a for loop to display a set number of prompts for each topic/hours studied (in order) as I'm doing now? I'm not looking for anyone to rewrite my program or anything like that, but rather give me some pointers with their code. Thanks a lot guys!
Edit: thank you so much for all the examples and pointers you've given me. I will play around with them and post some code of my own to let you know how it's working.

You will need to use an array or list, then loop through them. You can have two separate arrays, one to hold the topic names, and the other to hold the hours studies, or you can define a class that includes a topic name and hours studied and then have an array of elements of that class.
Bottom line, you need to learn how to use arrays or collections.

You can use a struct
typedef struct _element {
string topic;
double hoursStudying;
} element;
Then you can define an array of elements like this
element journal[ 4 ];
Now you can think of using loops to handle the array journal.
Try it yourself: write a complete program out of the above hints and let us know...
After doing that, try to transform the struct into a class figuring out what member functions are needed and then implementing them. Again, let us know...

I'd do something like:
cout << "Enter topic name or 'quit'";
while(true)
{
cin<< foo;
if(foo == 'quit')
break;
else
{
//Do stuff with foo
}
}
Obviously you'll want to handle weird input ("qUiT"), but that's the loop structure.

How could I use, for example, a do...while loop or even a for loop to display a set number of prompts for each topic/hours studied (in order) as I'm doing now?
Instead of creating a separate variable for, you should create an array to store your data. After that, use a loop to prompt and receive input. It can be a while-loop or a for-loop. (Generally, use a for-loop when you are certain how many times you want it to iterate. Use a while-loop when the number of times to iterate cannot be determined)
Example:
double hoursStudying[5] = {0};
for(int x=0; x<5; x++){ //5 can be replaced with a variable indicating array size
cout << "Time studying for " << topic << " " << x << ": ";
cin >> hoursStudying[x];
cin.ignore();
}
For displaying output, it will be the same. Just use a loop to iterate through the array values.
Example:
for(int x=0; x<5; x++){
cout << "For " << topic << " " << (x+1) << " you spent "
<< hoursStudying[x]<< " hours studying" << endl;
}

This is proper way to write programs in C++:
File Topic.h:
#pragma once
#include <sstream>
#include <string>
using namespace std;
class Topic {
string name;
double hours;
public:
Topic(string name, double hour);
~Topic();
void setName(const string & _name) {
name = _name;
}
void setHours(double & _hours) {
hours = _hours;
}
void addHours(double & _hours) {
hours += _hours;
}
string getName() const {
return name;
}
double getHours() const {
return hours;
}
string print() const;
};
File Topic.cpp
#include "Topic.h"
Topic::Topic(string name = "", double hour = 0.0) :
name(name), hours(hour) {
}
Topic::~Topic() {
}
string Topic::print() const {
ostringstream output;
output << "For " << name << " you spent " << hours << " hours studying.";
return output.str();
}
File Topics.h:
#pragma once
#include <vector>
#include <sstream>
#include <string>
#include "Topic.h"
using namespace std;
class Topics {
vector<Topic> topics;
public:
Topics();
~Topics();
void add(const Topic & topic) {
topics.push_back(topic);
}
Topic get(const unsigned int & index) const {
return topics[index];
}
string printAll() const;
};
File Topics.cpp:
#include "Topics.h"
Topics::Topics()
{
}
Topics::~Topics()
{
}
string Topics::printAll() const {
ostringstream output;
for (Topic topic : topics) {
output << topic.print() << endl;
}
return output.str();
}
File Source.cpp
#include <iostream>
#include <vector>
#include <sstream>
#include <string>
#include "Topic.h"
#include "Topics.h"
using namespace std;
Topic input() {
string name;
double hours;
cout << "Topic name: ";
cin >> name;
cout << "Time studying for " << name << ": ";
cin >> hours;
cout << endl;
return Topic(name, hours);
}
Topics inputCycle()
{
Topics topics;
int n;
cout << "How many topics you have ?" << endl;
cin >> n;
for (int i = 0; i < n; i++)
topics.add(input());
return topics;
}
void printAll(const Topics & topics) {
cout << topics.printAll() << endl;
}
int main()
{
printAll(inputCycle());
system("PAUSE");
return false;
}

Related

Issues with retrieving information from a class module for output within a switch statement

I know this may be something obvious to some with experience but I am in the middle of my first real class for C++ programming. I have come across something in my code that I have been trying to resolve without any success. I am trying to extract the sum of the total value of "m_cost" stored within a array that is inside of these class modules. I want to output the total value inside of a switch statement for print out. Just seeing if someone can point me in the right direction or if I have completely gone off-track with the logic.
Project Code section in question:
void materialsMenu()
{
Inventory record[MAX_REC];
int i, n;
cout << "\n=====Inventory Management=====\n";
cout << "\nHow many Materials are there to be used? : ";
cin >> n;
cout << "Enter " << n << " Materials\n";
for (i = 0; i < n; i++)
record[i].getdata();
cout << "\n\n---Material Information---\n";
cout << "\n" << setw(8) << "Item Name "
<< setw(10) << " Price per foot "
<< setw(19) << " Cost " << endl;
cout << endl << "-------------------------------------------" << endl;
for (i = 0; i < n; i++)
record[i].showdata();
}
void Inventory::getdata() {
cout << endl;
cout << "\nEnter Material Name : ";
cin >> itemName;
cout << "Enter Price Per Foot : ";
cin >> ppf;
cout << "Enter Total Length Needed in Feet (ft) : ";
cin >> length;
cout << endl;
m_cost = ppf*length;
m_costT=???????? **this is the issue**
}
Materials.H file contents:
#ifndef MATERIALS_H
using namespace std;
class Materials {
private:
char itemName[15];
float ppf;
float length;
double m_cost;
float m_costT;
public:
Materials()
{
ppf = 0;
length = 0;
m_cost = 0;
m_costT = 0;
}
Materials(int itemName, float ppf, float length, double m_cost, float
m_costT)
{
length = getLength();
ppf = getPpf();
m_cost = getCost();
m_costT = getTotal();
}
float getLength()
{
return length;
}
float getPpf()
{
return ppf;
}
double getCost()
{
return m_cost;
}
float getTotal()
{
return m_costT;
}
void getdata();
void showdata();
};
#endif // !MATERIALS_H
Consider something like this to hold your records. It's very simple, but it demonstrates the idea of one class holding another and shows information hiding and all sorts of other tidbits. You are struggling to get that total because the Record class shouldn't care about this. The total is a concept outside of the scope of a Record. And as such, it is very difficult to calculate this from where you wanted to do it. (Though it is possible, it breaks all sorts of C++ rules and should be avoided)
Example:
class Record;
class RecordHolder
{
public:
int GetTotal()
{
int retVal = 0;
for(int i=0; i<10; i++) // Magic number 10 for demo purposes only...
{
retVal += records[i].m_cost; // Or use a public get function.
}
return retVal;
}
private:
Record records[10]; // Magic number 10 for demo purposes only...
};
The RecordHolder could also do printing, add/removing records, etc. It controls the records array. The Records are just Records and don't care about such management.

So I'm having trouble understanding files in C++

I just started learning files and I understand how to set it up and get it to work. I have to write this program where I have to allow the user to enter some information and have the user also update and adjust any data, using binary.
So I can write up until the point where the user can write to and read from the file. But I don't know how to let the user adjust data or add data.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class client {
public:
string name;
int balance;
string id;
};
int main()
{
int ans;
int x;
string nameIn;
string adjName;
client client1;
ofstream out("client1.dat", ios::binary);
cout << "\nDo you want to add information or update info" << endl;
cin >> ans;
if (ans == 1)
{
cout << "\nPlease enter the name of your client" << endl;
cin >> nameIn;
x = nameIn.length();
if (x <= 10)
{
for (int i; i < 10; i++)
{
adjName[i] = nameIn[i];
}
}
else
{
for (int i = x; i < 10; i++)
{
adjName[i] = ' ';
}
}
client1.name = adjName;
cout << "\nPlease enter the balance of your client" << endl;
cin >> client1.balance;
cout << "\nPlease enter the id of your client" << endl;
cin >> client1.id;
cout << "\nThe name of your client is " << endl << client1.name
<< endl << "\nThe balance of your client is " << endl
<< client1.balance << endl << "\nThe id of your client is "
<< endl << client1.id;
out.write(reinterpret_cast<const char*> (&client1), sizeof(client));
}
/*
else if (ans == 2)
{
string answer, newName,line;
cout << "\nWhat name do you want to update? " << endl;
cin >> answer;
cout << "\nWhat is the new name?" << endl;
cin >> newName;
if (out)
}
*/
system("pause");
return 0;
}
so the name needs to be only 10 characters long, so that we can adjust/update it. It compiles and runs, but every time the compiler gets to the part where it checks the name length, it freaks out and says "debug assertion failed"
string subscript out of range.
Also a thing about this code-- if i run it without the bits where you adjust the name to a certain array length, the program runs, and stores everything nicely. But when I try to read back the .dat, it reads it back but exits with an access violation, forcing me to manually stop the debugging. What am I doing wrong?
this is the code for reading the file
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class client {
public:
string name;
int balance;
string id;
};
int main()
{
client client1;
char ans;
cout << "\nDo you want to view the information about your client?"
<< endl;
cin >> ans;
ifstream in("client1.dat", ios::binary);
if (ans == 'y' || ans == 'Y')
{
in.read(reinterpret_cast<char*> (&client1), sizeof(client));
cout << "The name is " << endl << client1.name << endl
<< "The balance is " << endl << client1.balance << endl
<< "The id is " << endl << client1.id << endl;
}
system("pause");
return 0;
}
As for the 1st part:
for (int i; i < 10; i++)
// ^
misses to initialize i to zero. Also what if the input was smaller than 10 characters? You're going to access the std::string out of bounds. You should replace the if/else and loops with simply
adjName = nameIn;
while(adjName.length() <= 10) {
adjName += ' ';
}
to get rid of the debug assertion.
For the 2nd part of the question, as already mentioned in the comments you cannot do this with a structure containing classes like std::string.
The reinterpret_cast<char*> (&client1) just obfuscates that std::string uses a pointer to the dynamically allocated character data internally, and that cannot be restored meaningfully when reading the stored data back later (hence the access violation you get).
A viable way might be to use something like
struct client {
char name[11];
int balance;
char id[5];
};
As I guess you need to do this for a homework exercise, and for this purpose that would probably be sufficient.
But you quickly can see the drawbacks, that the character data needs to be fixed in size and you cannot have arbitrary length strings. I never would use such for production ready code.
Another pitfall (as also mentioned) is, that int isn't represented in the same way (order of bytes used, i.e. endianess) in the same way for different CPU architectures. So the binary file can't be used portably with different computers.
The simplest solution is not to use a binary file, but a text formatted file and overload the std::ostream& operator<<(std::ostream&, const client&) and std::istream& operator>>(std::istream&, client&) output/input operators.
Or use some 3rd party library like boost::serialization or google protocol buffers, that supports de-/serialization to binary files.

std::_throw_out_of_range occurs from nowhere

I'm an absolute beginner in c++. Literally. It's just been a week.
Today I was writing a program to test how many iterations are needed to make a certain number palindromic.
Here is the code:
#include <iostream>
#include <string>
#include <algorithm>
/* This program calculates the steps needed
to make a certain number palindromic.
It is designed to output the values for
numbers 1 to 1000
*/
using namespace std;
class number
{
public:
string value;
void reverse();
};
void number::reverse()
{
std::reverse(value.begin(),value.end());
}
void palindrome(number num)
{
string n=num.value;
number reversenum, numsum, numsumreverse;
reversenum=num;
reversenum.reverse();
numsum.value=num.value;
numsumreverse.value=numsum.value;
numsumreverse.reverse();
int i=0;
while (numsum.value.compare(numsumreverse.value) !=0)
{
reversenum=num;
reversenum.reverse();
numsum.value=to_string(stoll(num.value,0,10)+stoll(reversenum.value,0,10));
numsumreverse.value=numsum.value;
numsumreverse.reverse();
num.value=numsum.value;
i++;
}
cout << "The number " << n << " becomes palindromic after " << i << " steps : " << num.value << endl;
}
int main()
{
number temp;
int i;
for (i=1; i<1001; i++)
{
temp.value=to_string(i);
palindrome(temp);
}
return 0;
}
It goes on smooth for numbers upto 195. But, in case of 196 I get an error.
It says:
terminate called after throwing an instance of 'std::out_of_range'
what(): stoll
I cannot make out what to do. I tried starting from 196 but the error persisted. Any help will be greatly appreciated. :)
UPDATE: This time I tried to do it using ttmath library. But arghs! It again stops at 195 and doesn't even report an error! I might be doing something foolish. Any comments would be appreciated. Here's the updated code:
#include <iostream>
#include <string>
#include <algorithm>
#include <ttmath/ttmath.h>
/* This program calculates the steps needed
to make a certain number palindromic.
It is designed to output the values for
numbers 1 to 1000
*/
using namespace std;
class number
{
public:
string value;
void reverse();
};
void number::reverse()
{
std::reverse(value.begin(),value.end());
}
template <typename NumTy>
string String(const NumTy& Num)
{
stringstream StrStream;
StrStream << Num;
return (StrStream.str());
}
void palindrome(number num)
{
string n=num.value;
number reversenum, numsum, numsumreverse;
reversenum=num;
reversenum.reverse();
numsum.value=num.value;
numsumreverse.value=numsum.value;
numsumreverse.reverse();
ttmath::UInt<100> tempsum, numint, reversenumint;
int i=0;
while (numsum.value.compare(numsumreverse.value) !=0)
{
reversenum=num;
reversenum.reverse();
numint=num.value;
reversenumint=reversenum.value;
tempsum=numint+reversenumint;
numsum.value=String<ttmath::UInt<100> >(tempsum);
numsumreverse.value=numsum.value;
numsumreverse.reverse();
num.value=numsum.value;
i++;
}
cout << "The number " << n << " becomes palindromic after " << i << " steps : " << num.value << endl;
}
int main()
{
number temp;
int i;
for (i=196; i<1001; i++)
{
temp.value=to_string(i);
palindrome(temp);
}
return 0;
}
UPDATE: It's solved. Some research suggested that 196 might be a Lychrel Number. And the result I was getting after implying the ttmath library is just reassuring that my algorithm works. I have tried it out for all the numbers upto 10000 and it gave out the perfect results. Here is the final code:
#include <iostream>
#include <string>
#include <algorithm>
#include <ttmath/ttmath.h>
#include <limits>
/* This program calculates the steps needed
to make a certain number palindromic.
It is designed to output the values for
numbers inside a desired range
*/
using namespace std;
string LychrelList;
int LychrelCount=0;
class number
{
public:
string value;
void reverse();
};
void number::reverse()
{
std::reverse(value.begin(),value.end());
}
template <typename NumTy>
string String(const NumTy& Num)
{
stringstream StrStream;
StrStream << Num;
return (StrStream.str());
}
void palindrome(number num)
{
string n=num.value;
number reversenum, numsum, numsumreverse;
reversenum=num;
reversenum.reverse();
numsum.value=num.value;
numsumreverse.value=numsum.value;
numsumreverse.reverse();
ttmath::UInt<100> tempsum, numint, reversenumint;
int i=0;
while ((numsum.value.compare(numsumreverse.value) !=0) && i<200)
{
reversenum=num;
reversenum.reverse();
numint=num.value;
reversenumint=reversenum.value;
tempsum=numint+reversenumint;
numsum.value=String<ttmath::UInt<100> >(tempsum);
numsumreverse.value=numsum.value;
numsumreverse.reverse();
num.value=numsum.value;
i++;
}
if (i<200) cout << "The number " << n << " becomes palindromic after " << i << " steps : " << num.value << endl;
else
{
cout << "A solution for " << n << " could not be found!!!" << endl;
LychrelList=LychrelList+n+" ";
LychrelCount++;
}
}
int main()
{
cout << "From where to start?" << endl << ">";
int lbd,ubd;
cin >> lbd;
cout << endl << "And where to stop?" << endl <<">";
cin >> ubd;
cout << endl;
number temp;
int i;
for (i=lbd; i<=ubd; i++)
{
temp.value=to_string(i);
palindrome(temp);
}
if (LychrelList.compare("") !=0) cout << "The possible Lychrel numbers found in the range are:" << endl << LychrelList << endl << "Total - " << LychrelCount;
cout << endl << endl << "Press ENTER to end the program...";
cin.ignore(numeric_limits<streamsize>::max(), '\n');
string s;
getline(cin,s);
cout << "Thanks for using!";
return 0;
}
It's a really awesome community. Special thanks to Marco A. :)
UPDATE AGAIN: I've devised my own add() function that cuts the program's dependency on external libraries. It resulted in a smaller executable and faster performance too. Here is the code:
#include <iostream>
#include <string>
#include <algorithm>
#include <limits>
/* This program calculates the steps needed
to make a certain number palindromic.
It is designed to output the values for
numbers inside a desired range
*/
using namespace std;
string LychrelList;
int LychrelCount=0;
string add(string sA, string sB)
{
int iTemp=0;
string sAns;
int k=sA.length()-sB.length();
int i;
if (k>0){for (i=0;i<k;i++) {sB="0"+sB;}}
if (k<0) {for (i=0;i<-k;i++) {sA="0"+sA;}}
for (i=sA.length()-1;i>=0;i--)
{
iTemp+=sA[i]+sB[i]-96;
if (iTemp>9)
{
sAns=to_string(iTemp%10)+sAns;
iTemp/=10;
}
else
{
sAns=to_string(iTemp)+sAns;
iTemp=0;
}
}
if (iTemp>0) {sAns=to_string(iTemp)+sAns;}
return sAns;
}
void palindrome(string num)
{
string n=num;
string reversenum, numsum, numsumreverse;
numsum=num;
numsumreverse=numsum;
reverse(numsumreverse.begin(),numsumreverse.end());
int i=0;
while ((numsum.compare(numsumreverse) !=0) && i<200)
{
reversenum=num;
reverse(reversenum.begin(),reversenum.end());
numsum=add(num,reversenum);
numsumreverse=numsum;
reverse(numsumreverse.begin(),numsumreverse.end());
num=numsum;
i++;
}
if (i<200) cout << "The number " << n << " becomes palindromic after " << i << " steps : " << num << endl;
else
{
cout << "A solution for " << n << " could not be found!!!" << endl;
LychrelList=LychrelList+n+" ";
LychrelCount++;
}
}
int main()
{
cout << "From where to start?" << endl << ">";
int lbd,ubd;
cin >> lbd;
cout << endl << "And where to stop?" << endl <<">";
cin >> ubd;
cout << endl;
string temp;
int i;
for (i=lbd; i<=ubd; i++)
{
temp=to_string(i);
palindrome(temp);
}
if (LychrelList.compare("") !=0) cout << "The possible Lychrel numbers found in the range are:" << endl << LychrelList << endl << "Total - " << LychrelCount;
cout << endl << endl << "Press ENTER to end the program...";
cin.ignore(numeric_limits<streamsize>::max(), '\n');
string s;
getline(cin,s);
cout <<endl << "Thanks for using!";
return 0;
}
You guys here have helped me a lot to find my own way. Thanks everyone. :)
You're overflowing long long since the last two valid values of num.value and reversenum.value are 7197630720180367016 and 6107630810270367917 which, added together, are way above the maximum size of a long long (9223372036854775807 on my machine). That will yield a negative value and spoil your next call to stoll
std::out_of_range is thrown if the converted value would fall out of the range of the result type or if the underlying function (std::strtol or std::strtoll) sets errno to ERANGE.
(reference)
If you're trying to get the next smallest palindrome, you should use another approach like the one I explained here.
You can find a Live Example here
If you prefer to/must continue with your approach you should either do the addition manually on the strings or use a bigint library (again take a look at here and modify the plusOne() function to your liking)
From http://www.cplusplus.com/reference/string/stoll/
If the value read is out of the range of representable values by a long long, an out_of_range exception is thrown.
The ll data type cant handle the string length. My debugger tells me 196 breaks on the value
std::stoll (__str=\"9605805010994805921-\", __idx=0x0, __base=10)
The long long is too small.
You might want to do the addition on the strings themselves, without resorting to a numeric type.

Validate case pattern (isupper/islower) on user input string

I need to write a program that checks if the user-provided first and last names are correctly typed. The program needs to validate that only the first letter of each name part is uppercase.
I managed to write code that checks the first character of the input. So I have a problem when for example "JOHN" is entered.
A correct input would be for example "John Smith".
Here's the code:
#include <iostream>
#include <string>
using namespace std;
int main ()
{
std::string str;
cout << "Type First Name: ";
cin >> str;
if(isupper(str[0]))
{
cout << "Correct!" <<endl;
}
else
{
cout << "Incorrect!" <<endl;
}
system("pause");
return 0;
}
The simplest thing you can do is to use a for/while loop. A loop will basically repeat the same instruction for a number of n steps or until a certain condition is matched.
The solution provided is pretty dummy, if you want to read the first name and last name at the same time you will have to spit the string via " " delimiter. You can achieve this result using strtok() in C/C++ or with the help of find in C++. You can see some examples of how to split here.
You can easily modify your code to look like this:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
std::string str;
std::vector<std::string> data = { "First", "Last" };
int j;
for (int i = 0; i < 2; i++) {
cout << "Type " << data[i] << " Name: ";
cin >> str;
if (isupper(str[0])) {
for (j = 1; j < str.size(); j++) {
if (!islower(str[j]))
{
cout << "InCorrect!" << endl;
break; // Exit the loow
}
}
if(j==str.size())
cout << "Correct!" << endl;
}
else {
cout << "InCorrect!" << endl;
}
}
system("pause");
return 0;
}

Sorting names between a Student class

edit. I want to thank the two people who helped me in my code. I fixed my coding as of 7:22 PM PST 9/25/2014. Still having trouble with the sorting though.
So I'm trying to teach myself how to use C++ in order to get ahead of my programming class in school. I've already taken Java so I'm relatively familiar with the structure of the coding but not exactly sure what to be typing. This practice problem is:
1)Ask the user how many people he wants to enter into the list.
2)Read 3 strings, then turn that info into a student class and put the student inside a vector.
3)Sort the list by name. (Extra credit would be to sort the list by Student ID)
4)Print the info of each student in the list.
5)Ask user while answer is 'Y', search the list for a name and print the info correlating to the name
While in Java, this seems pretty easy, I'm having an extremely hard time understanding what is going on in C++.
I currently only have 1, 2, 4 and 5 done. This is what I have so far.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>
#include <fstream>
#include <iomanip>
using namespace std;
class Student
{
string myName, myStudentID, myClassID;
public:
Student(string name, string studentID, string classID)
{
myName = name;
myStudentID = studentID;
myClassID = classID;
}
string getName() { return myName; }
string getStudentID() { return myStudentID; }
void printInfo() { cout << myName << setw(15) << myStudentID << setw(10) << myClassID << endl; }
};
int main()
{
int num;
std::vector<Student> studentList;
cout << "How many students do you wish to add to the student list ? " << endl;
cin >> num;
cin.ignore();
for (int a = 0; a < num; a++)
{
string inputName, inputStudentID, inputClassID;
//get name
cout << "Please enter the Student name : ";
getline(cin, inputName);
//get student ID
cout << "Please enter the Student ID number : ";
getline(cin, inputStudentID);
//get class ID
cout << "Please enter the Student class ID : ";
getline(cin, inputClassID);
Student thisStudent(inputName, inputStudentID, inputClassID);
studentList.push_back(thisStudent);
cout << endl;
}
//sort(studentList.begin(), studentList.end());
/*
I never figured out how to sort the list by name.
I do not know how to compare the name of studentList[0] and studentList[1]
to put them in alphabetical order.
*/
cout << endl;; // FORMATTING
cout << "The student list has a size of " << studentList.size() << endl;
cout << endl;; // FORMATTING
cout << "Student Name" << setw(15) << "Student ID" << setw(10) << "Class ID" << endl;
for (int a = 0; a < studentList.size(); a++)
{
studentList[a].printInfo();
}
cout << endl;; // FORMATTING
string searchedName;
char answer;
do
{
cout << endl;; // FORMATTING
cout << "Please type the name of the person you want to search for: ";
getline(cin, searchedName);
for (int a = 0; a < studentList.size(); a++)
{
if (searchedName.compare(studentList[a].getName()) == 0)
{
studentList[a].printInfo();
break;
}
else
if (a == (studentList.size() - 1)) //If went to end of the list, tell them name not found.
cout << "There is no " << searchedName << " in the list. \n";
}
cout << "Would you like to search for another person? \n";
cout << "Y for Yes, N for No. \n";
cin >> answer;
cin.ignore();
} while (answer == 'Y' || answer == 'y');
return 0;
}
You could create a static compare function in class Student to use with std::sort
class Student
{
string myName, myStudentID, myClassID;
// ...
static bool compare_name(const Student & lStudent, const Student & rStudent)
{return (lStudent.myName < rStudent.myName);}
};
// ...
std::sort(studentList.begin(), studentList.end(), Student::compare_name);
or if your compiler supports lambda functions:
std::sort(studentList.begin(), studentList.end(),
[studentList](const Student & lStudent, const Student & rStudent)
{return (lStudent.myName < rStudent.myName);});