Display their names in ascending order with respect to their ages? - c++

The stated problem is "Write a program that takes names and ages of 10 employees as input in a 2D char array and display their names in ascending order with respect to their ages".
I've pasted below what I have so far, but I don't know how to display the names in ascending order with respect to age. What am I missing?
#include<iostream.h>
#include<string.h>
void sort(int[],int);
void main(void)
{
char a[10][5],x;
int b[5],i,j;
for(j=0;j<=5;j++)
{
cout<<"Enter name of Employee:";
for(i=0;i<10;i++)
{
cin>>x;
x=a[j][i];
}
cout<<"Enter Employee's age:";
cin>>b[j];
cout<<endl;
}
sort(b,j);
cout<<"Name of Employee \t\t Age \n";
for(j=0;j<5;j++)
{
for(i=0;i<10;i++)
{
x=a[j][i];
cout<<"\t"<<x;
}
cout<<"\t\t"<<b[j]<<"\n";
}
}
void sort(int x[],int size)
{
int temp,i,j;
for(j=0;j<size;j++)
{
for(i=0;i<size;i++)
{
if(x[i]>x[i+1])
{
temp=x[i+1];
x[i+1]=x[i];
x[i]=temp;
}
}
}
}

I will point you in the right direction.
You should define struct to hold a Name and age pair, then make a comparison function.
Then you simply need to populate a vector of your structs then sort them using the sorting function provided by the standard library, iterate through the vector printing out the contents, you can define stream operator of the struct you made to simplify them.
http://www.cplusplus.com/doc/tutorial/structures/
http://en.cppreference.com/w/cpp/algorithm/sort
http://en.cppreference.com/w/cpp/container/vector
http://www.java2s.com/Code/Cpp/Overload/Overloadstreamoperator.htm
EDIT: and please for all that is good, use a std::string to hold the names.
http://www.cplusplus.com/reference/string/string/
using an char array like you are is pretty much deprecated.
I started writing this before the other solution, because I would rather see what C++ is capable of not what your lecture is feeding you.
#include <string>
#include <vector>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <fstream>
struct employee
{
employee(const std::string& name_, unsigned age_)
: name(name_), age(age_) {}
std::string name;
unsigned age;
};
std::ostream& operator<<(std::ostream& os, const employee& e)
{
os << e.name << " " << e.age;
return os;
}
bool comp_age(const employee& e1, const employee& e2)
{
return e1.age<e2.age;
}
int main()
{
std::vector<employee> employees;
employees.reserve(5);
for(unsigned i=0; i!=5; ++i)
{
std::string name;
unsigned age;
std::cout << "Name:" << std::flush;
std::cin >> name;
std::cout << "Age:" << std::flush;
if(!std::cin >> age)
{
std::cerr << "not an number" << std::endl;
--i;
continue;
}
//note you should catch any failure to parse to int here
employees.push_back(employee(name, age));
}
std::sort(employees.begin(), employees.end(), comp_age);
std::copy( employees.begin(), employees.end(),
std::ostream_iterator<employee>(std::cout, "\n"));
return 0;
}
So this is an alternative, but PLEASE learn the concepts I list above which constitutes this example.

You should start by changing void main to int main, because void main is not valid C++. Then you change the #includes to be real C++ header files not what you have:
#include <iostream>
#include <string>
Then you should give meaningful names to your variables. It's impossible to follow the code in a sea of as and bs.
Then you need to sort the employees by their age. You already have a sorting algorithm written there, so you only need to adapt it to swap all the employee data instead of swapping just their ages, while still doing the comparisons only on their age. This will be easier if instead of two separate arrays for the employee data, you kept instead a single array of a structure that holds both the name and age of the employee:
struct employee {
std::string name;
int age;
};
Once sorted, you can just loop through all the employees an print their names.
I believe there are a few more issues in the code, but they should be easy to fix with a good reference and some debugging time. If you have trouble, you can post a new question with what you've got so far, and explain what is stumping you.
This would all be much better if you just used the C++ standard library, but unfortunately some teachers decide to teach Crippled++ to their students instead of proper C++ :(
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
// treat an employee as a single unit
struct employee {
std::string name;
int age;
};
// a comparison function to compare two employees by their age
// should return true if the first one is younger than the second one
// this will be used for sorting later
bool is_younger(employee const& l, employee const& r) {
return l.age < r.age;
}
int main()
{
// a vector with 5 employees
std::vector<employee> employees(5);
for(j=0;j<=5;++j)
{
std::cout << "Enter name of Employee: "
// read the entire name at once
getline(std::cin, employees[j].name);
std::cout << "Enter Employee's age:";
// read the age
std::cin >> employees[j].age;
}
// sort all the employees using the comparison function written above
std::sort(employees.begin(), employees.end(), is_younger);
std::cout<<"Name of Employee \t\t Age \n";
for(j=0;j<5;++j)
{
std::cout << employees[j].name;
std::cout << "\t\t" << employees[j].age << "\n";
}
}

Use a std::multimap (a key/value store, fitting your needs), which is weakly sorted ascending by default. Your key is the age and the value is the name. For printing the values just use iterators. std::multimap is chosen because there could potentially be employees with the same age.

#include <iostream.h>
int main() {
int a;
int b;
int sum;
std::cout << "Enter two numbers" << std::endl;
std::cout << "Enter the value of a" << std::endl;
std::cin >> a;
std:: cout << "Enter the value of b" << std::endl;
std::cin >> b;
sum = a + b;
std::cout << sum << std::endl;
return 0;
}

Related

I need help in structure in c++

The program is to take a structure with object name "st" will take age and then first and last name than standard
But it is saying this error
(main.cpp:33:10: error: invalid use of non-static member function ‘void Student::age(int)’)
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
struct Student{
static string f,l;
static int a,s;
void age(int ag);
void first_name(string fi)
{
f=fi;
}
void last_name(string la)
{
l=la;
}
void standard(int st)
{
s=st;
}
};
void Student :: age( int ag)
{
a=ag;
}
int main() {
Student st;
cin >> st.age >> st.first_name >> st.last_name >> st.standard;
cout << st.age << " " << st.first_name << " " << st.last_name << " " << st.standard;
return 0;
}
Right now it's really unclear what you're trying to achieve with your code.
First of all, your problem is because trying to to put some input into member functions that take arguments, you need to get your input into temporary arguments and pass them, you should also rename your member function to set_age, set_first_name, etc. to indicate what they're doing.
Student st;
int age;
std::string first_name;
std::string last_name;
int standard;
std::cin >> age >> first_name >> last_name >> standard;
st.set_age(age);
st.set_first_name(first_name);
st.set_last_name(last_name);
st.set_standard(standard);
Then you're trying to output them using the same functions without calling them again, but even if you did, they return void, so nothing. You need a different set of member functions to access those variables.
class Student{
int age;
/* rest of the code */
int get_age() const {
return age;
}
};
int main() {
Student student;
student.set_age(10);
std::cout << student.get_age() << '\n';
}
It also looks like you don't know what static means inside a class, right now all your instances of Student class will share age, first_name, last_name and standard, which is probably not what you ment.

Passing a string by reference in c++

I am working on a code for my c++ class. The assignment is to read the names from 2 different txt files(already in my directory) and find if the string/name that the user searched for matches any of the names already in the files. My code seems good to me, but I am getting an error in my function prototype saying "string was not declared in this scope." Any solutions? My code is here as follows:
#include <fstream>
#include <string>
#include <vector>
void boysfunc(string&, string&);
void girlsfunc(string&, string&);
using namespace std;
int main()
{
vector<string> boysnames;
vector<string> girlsnames;
string boysname, girlsname;
ofstream outputFile;
cout << "Enter a boy's name, or N if you do not want to
enter a name: ";
cin >> boysname;
cout << "Enter a girl's name, or N if you do not want to
enter a name: ";
cin >> girlsname;
if (boysname != "N")
{
boysfunc(boysname, boysnames);
}
if (girlsname != "N")
{
girlsfunc(girlsname, girlsnames);
}
}
void boysfunc(string &boysname, string &boysnames)
{
outputFile.open("BoysNames.txt");
while(outputFile >> boysnames)
{
/*Declare local variable count to use as a counter*/
int count = 0;
if (boysnames(count) == boysname)
{
outputFile.close();
cout << "The name " << boysname << " is very
popular among boys.";
return;
}
else
{
count++;
}
}
}
void girlsfunc(string &girlsname, string &girlsnames)
{
outputFile.open("GirlsNames.txt");
while(outputFile >> girlsnames)
{
/*Declare local variable count to use as a counter*/
int count = 0;
if(girlsnames(count) == girlsname)
{
outputFile.close();
cout << "The name " << boysname << " is very
popular among girls.";
return;
}
else
{
count++;
}
}
}
There are two major errors that you need to fix here.
using namespace std; must be written before the use of strings if you wish to omit std:: before writing string. Otherwise, you can write std::string& in the function declarations.
boysfunc() and girlsfunc() are taking vector<string>& as the second argument, whereas you incorrectly mentioned string& in the functions' declaration and definition. Fix that.
In this snippet
string s = "hello";
using namespace std;
the type string is not known to the compiler. That's what using namespace std; does. It basically turns string into std::string.
You could swap the 2 lines above, and it will work, but I highly recommend just saying std::string explicitly everywhere. I'm sure your IDE will let you do this easily.

Checking user input if is equal to a array element

I have a string array with multiple names.
I would like to check using an if statement if the user input is equal to any of the names.
For example:
names[5] = {'david','rares','tudor','john','jay'}
cin>>name;
And now i would like to check if name is equal to any of the elements in the array.
Very Bad Example:
if(name == names)
{
cout<<"you can use this name. Name: "<<name;
}
As pointed out by user4581301, 'david' isn't a string but a multibyte character (and most probably not a valid one either). If you want to keep a set of names and check if some name exists in it, you could use a std::set or std::unordered_set instead of an array. Example:
#include <iostream>
#include <set>
#include <string>
int main() {
std::set<std::string> names = {"david", "rares", "tudor", "john", "jay"};
std::string name;
std::cin >> name;
if(names.count(name)) // or names.contains(name) in C++20
std::cout << "found\n";
else
std::cout << "not found\n";
}
I would suggest using a vector to store the names so you know your size. If you must use a static array, make sure to save the current size and update it whenever removing/adding names.
Somebody may have a more efficient solution, but you can linearly search through the array using a for loop.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string name;
string names[5] = {"david","rares","tudor","john","jay"};
cout << "Enter name: ";
cin >> name;
for (int i = 0; i < 5; i++)
{
if(names[i] == name)
{
cout << name << " was found in the array." << endl;
return 0;
}
}
cout << name << " wasn't found in the array." << endl;
return 0;
}
This solution won't work for case sensitive names (David and david are considered two seperate names).
You can do something like this:
#include <iostream>
#include <algorithm>
int main()
{
const char * v [] = { "david", "rares", "tudor", "john", "jay" };
std::string name;
std::cin >> name;
auto result = std::find (std::begin (v), std::end (v), name);
if (result != std::end (v))
std::cout << name << " is valid\n";
}
although please note that most people would use std::vector <std::string> to hold the list of strings.
Live demo

How to implement istream& overloading in C++?

I can't get this code to output the file info. How would I use ostream overloading to output this? Or do I have to do it some other way? I can't figure it out.
Which C++ sorting algorithm would be the best to use to sort the info ascending order?
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <stdlib.h> // needed to use atoi function to convert strings to integer
using namespace std;
struct Employees
{
string employeeName;
string employeeID;
int rate;
int hours;
};
istream& operator >> (istream& is, Employees& payroll)
{
char payrollStuff[256];
int pay = atoi(payrollStuff); // use atoi function to convert string to int
is.getline(payrollStuff, sizeof(payrollStuff));
payroll.employeeName = payrollStuff;
is.getline(payrollStuff, sizeof(payrollStuff));
payroll.employeeID = payrollStuff;
is.getline(payrollStuff, sizeof(payrollStuff));
payroll.rate = atoi(payrollStuff);
is.getline(payrollStuff, sizeof(payrollStuff));
payroll.hours = atoi(payrollStuff);
return is;
};
int main()
{
const int SIZE = 5; // declare a constant
Employees payroll_size[5];
ifstream myFile;
myFile.open("Project3.dat");
if(myFile.fail()) //is it ok?
{
cerr << "Input file did not open please check it" << endl;
}
else
for (int i=0; i< 5; i++)
{
myFile >> payroll_size[i];
}
myFile.close();
return 0;
}
Just overload the operator in the same way you did for the >>. For example:
ostream& operator<<(ostream& os, Employees& payroll)
{
os << payroll.employeeName << " " << payroll.employeeID << " " << payroll.rate << " " << payroll.hours << "\n";
return os;
}
Then, in a loop, you can just iterate over the array and print out each of the Employees using <<.
On a side note, if you are checking if the file opened, it is better to use the dedicated function std::ifstream::is_open.
For sorting your entries, it is best that you use std::sort, with a custom predicate for whatever criteria you want to sort with. As an example, if you wanted to sort based on the name of the Employee in alphabetical order, you would use the following command:
sort(payroll_size, payroll_size + 5, [](const Employee& a, const Employee& b) { return a.employeeName < b. employeeName; });

need help with vector out of range error

guys, I'm reading from a file and input into a vector, but I keep getting a pop up box with: "vector employees out of range!" error. It is like if I'm trying to access pass the last index in the vector, but if that's the case I don't see... any help appreciated
text file:
123 vazquez 60000
222 james 100000
333 jons 50000
444 page 40000
555 plant 40000
code:
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
using namespace std;
struct employees { int id; string lname; double salary; };
void getData(vector<employees>& list, ifstream& inf);
int i = 0;
int main()
{
string filename("file2.txt");
vector<employees> list;
ifstream inf;
inf.open(filename);
getData(list, inf);
inf.close();
for(unsigned int j = 0; j < list.size(); j++)
{
cout << list[j].id << " " << list[i].lname << endl;
}
system("pause");
return 0;
}
void getData(vector<employees>& list, ifstream& inf)
{
int i = 0;
while(inf)
{
inf >> list[i].id >> list[i].lname >> list[i].salary;
i++;
}
}
When you pass list into getData(), it has zero elements in it. You then try to access the element at index i (starting at 0), but there is no such element, hence the error.
You need to insert new elements into the container; the easiest way to do this would be to create a temporary object, read the data into that object, and then insert that object into the container.
employee e;
while (inf >> e.id >> e.lname >> e.salary)
list.push_back(e);
Note that this also fixes your incorrect input loop. In your incorrect loop, the stream could reach EOF or otherwise fail during one of the reads in the loop, but you don't detect that until after you've incremented i.
In your while loop in getData, you need to push_back an employees each time. Or you can define the >> operator for your employees class, and you wouldn't even need the getData function, you could just past an istream_iterator into the vector constructor.
Example using istream_iterator:
#include <iostream>
#include <vector>
#include <string>
#include <iterator>
struct employee { int id; std::string lname; double salary; };
std::istream& operator>>(std::istream& is, employee& e) {
return is >> e.id >> e.lname >> e.salary;
}
int main() {
std::string filename("file2.txt");
std::ifstream inf;
inf.open(filename); //add error checking here
std::vector<employee> list((std::istream_iterator<employee>(inf)), std::istream_iterator<employee>());
for (std::vector<employee>::iterator iter = list.begin(); iter != list.end(); ++iter) {
std::cout << iter->id << " " << iter->lname << std::endl;
}
return 0;
}
list[i].lname should be list[j].lname