Sorting and Calculating Wage from Struct Array [closed] - c++

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I have to calculate the wage for each employee. How would I write a function to do this?
And how would I sort the employees according to their wage?
The data file looks like this: I think I have to convert int to string or the other way around. I know that The function for calculating wage is wrong. Thanks.
A.Smith 20001 25 40
T.Philip 20002 20 35
S.Long 20003 15 50
G.Santos 20004 30 30
F.Farkas 20005 22 55
and this is my code that I am trying to write:
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <stdlib.h>
using namespace std;
struct Record
{
string name;
int id;
double rate;
int hrWorked;
double wage;
};
void read_file(string[], int);
void calculate_wage(Record& payroll);
int main()
{
int e = 5;
Record payroll[5];
string s[5];
cout << "Your entered file is: " << endl;
read_file(s, e);
calculate_wage(payroll);
system("pause");
return 0;
}
void read_file(string s[], int e)
{
ifstream myFile;
myFile.open("Project 3.dat");
string str;
int i = 0;
if (myFile.is_open())
{
while (getline(myFile, str))
{
s[i++] = str;
cout << str << endl;
}
myFile.close();
}
else
{
cout << "No Data Found!" << endl;
}
}
void calculate_wage (Record& payroll) // i know this part isnt right but im not sure what to do for this
{
char emplresult[256]; // need to convert int to string
payroll.wage = atoi(emplresult);
payroll.rate = atoi(emplresult);
payroll.hrWorked = atoi(emplresult);
for (int i = 0; i < 5; i++)
{
payroll[i].wage = payroll[i].rate * payroll[i].hrWorked;
}
}

use std algorithms, it will make your code readable and maintainable. For example you can sort your objects with std::sort:
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
struct Record
{
Record(std::string name, double wage) : name(name), wage(wage) {};
std::string name;
int id;
double rate;
int hrWorked;
double wage;
};
int main() {
using Records = std::vector<Record>;
Records records;
records.push_back(Record("Pedro",20));
records.push_back(Record("Andres",10));
records.push_back(Record("Santiago",15));
std::sort(records.begin(),records.end(),
[](auto& lhs, auto& rhs) {
return lhs.wage < rhs.wage;
});
for (const auto& r : records) {
std::cout << "Name: " << r.name << " wage: " << r.wage << "\n";
}
}
which outputs the sorted records:
Name: Andres wage: 10
Name: Santiago wage: 15
Name: Pedro wage: 20
I hope this gives you inspiration for your code!

Related

Unable to assign a range sub-string to an array of strings. c++

So I'm unable to create a substring cut using ranges. I am making an airport program where you feed the program a txt.file and it has to divide the lines I get from it into different strings. For instance, I have the following text data:
CL903 LONDON 41000 14.35 08906 //number of flight, destination, price, etc.
UQ5723 SYDNEY 53090 23.20 12986
IC5984 TORONTO 18030 04.45 03260
AM608 TOKYO 41070 18.45 11315
so the first string will be on the lines of this (variables are in Spanish):
numVuelo[n] = M[n].substr(0,5)
this line will work perfectly, but when I move to the next one (from 7 to 14), it tells me that it's out of range, even though It's between the 0 and 31st values of the length of the string.
M[n] gets all of the strings on the text, I'm using Codeblocks and a class style with header and all. I'll copy the code below...
This is my header Vuelo.h:
#ifndef VUELO_H
#define VUELO_H
#include <iostream>
#include <fstream>
#include <string>
#define NUM_FLIGHTS 10
using namespace std;
class Vuelo
{
public:
Vuelo(int N);
virtual ~Vuelo();
void setM();
void setNumVuelo(string _numVuelo, int n);
void setDestino(string _destino, int n);
void setPrecio(string _precio, int n);
private:
string M[NUM_FLIGHTS];
string numVuelo[NUM_FLIGHTS];
string destino[NUM_FLIGHTS+1]; //somehow "destino" doesn't work without the +1 but everything else does
float precio[NUM_FLIGHTS];
Then, on another code called Vuelo.cpp I have the following
#include "Vuelo.h"
Vuelo::Vuelo(int N)
{
M[N] = { };
numVuelo[N] = { };
destino[N] = { };
precio[N] = { };
}
Vuelo::~Vuelo()
{
//nope
}
void Vuelo::setM()
{
int c = 1;
string s;
ifstream F ("flights.txt");
if(F.is_open())
{
while (!F.eof())
{
getline(F,s);
M[c] = s;
cout << M[c] << endl;
c++;
}
//sets all values
for(c = 0; c < NUM_FLIGHTS; c++)
{
setNumVuelo(M[c],c);
setDestino(M[c],c);
setPrecio(M[c],c);
}
F.close();
}
else
{
cout << "ERROR document wasn't found" << endl;
}
}
void Vuelo::setNumVuelo(string _numVuelo, int n)
{
numVuelo[n]= _numVuelo.substr(0,5); //this works
cout << numVuelo[n] <<endl;
}
void Vuelo::setDestino(string _destino, int n)
{
destino[n] = _destino.substr(7, 13); //PROBLEM HERE
cout << destino[n] << " " << destino[n].length() << endl;
}
void Vuelo::setPrecio(string _precio, int n)
{
string p = _precio.substr(15,19); //PROBLEM HERE
precio[n] = atof(p.c_str());
cout << precio[n] <<endl;
}
And finally my main looks like this:
#include "Vuelo.h"
#include <iostream>
#include <fstream>
#include <string>
#define NUM_FLIGHTS 10
using namespace std;
int main()
{
cout << "Bienvenido, reserva tu vuelo!" << endl;
cout << "-----------------------------------" << endl;
Vuelo* flight = new Vuelo(NUM_FLIGHTS);
flight->setM();
return 0;
}
Thanks :)

Iterate over array of objects from txt file

I have file with records separated by comas:
cities.txt:
1,NYC
2,ABQ
...
I would like to iterate over each row: ids and names. I have created the code:
#include <iostream>
#include <string>
using namespace std;
class City {
int id;
string name;
public:
City() {}
City(int id, int name)
{
this->id = id;
this->name = name;
}
void load_file()
{
ifstream v_file("cities.txt");
if (v_file.is_open()) {
while (!v_file.eof()) {
//...
}
}
v_file.close();
}
}
int main()
{
City array_city[1000];
array_city.load_file();
return 0;
}
Could you tell me how to load all rows to array array_city and iterate over it? I don't know what to place in while block in load_file method. I don't know weather, the method load_file should have void type. Unfortunately I have to do it on arrays.
It's not a good idea to use EOF in a while loop. Read more in Why is iostream::eof inside a loop condition considered wrong?
In c++, vectors should be preferred over arrays. However, your teacher knows something more to suggest using an array here. For that reason I am providing a solution with an array:
Read the file line by line
Extract the id and the string
Assign it to the i-th cell of the array
Code:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
class City {
int id;
string name;
public:
City() {}
City(int id, string name) : id(id), name(name)
{
}
void print()
{
cout << "ID = " << id << ", name = " << name << endl;
}
};
void load_file(City* cities, const int n)
{
ifstream v_file("cities.txt");
if (v_file.is_open()) {
int number, i = 0;
string str;
char c;
while (v_file >> number >> c >> str && c == ',' && i < n)
{
//cout << number << " " << str << endl;
cities[i++] = {number, str};
}
}
v_file.close();
}
int main()
{
City cities[4]; // assuming there are 4 cities in the file
load_file(cities, 4);
for(unsigned int i = 0; i < 4; ++i)
cities[i].print();
return 0;
}
Same solution with std::vector, if you are interested. =) If you haven't been taught about them, I suggest you skip that part and come back later when you do that in the course.
Use a vector of City. Read the file line by line, and push back into the vector every line you read, by constructing an instance of your class, and you are done!
Example:
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
using namespace std;
class City {
int id;
string name;
public:
City() {}
City(int id, string name) : id(id), name(name)
{
}
void print()
{
cout << "ID = " << id << ", name = " << name << endl;
}
};
void load_file(vector<City>& cities)
{
ifstream v_file("cities.txt");
if (v_file.is_open()) {
int number;
string str;
char c;
while (v_file >> number >> c >> str && c == ',' && i < n)
{
//cout << number << " " << str << endl;
cities.push_back({number, str});
}
}
v_file.close();
}
int main()
{
vector<City> cities;
load_file(cities);
for(unsigned int i = 0; i < cities.size(); ++i)
cities[i].print();
return 0;
}
Input:
Georgioss-MacBook-Pro:~ gsamaras$ cat cities.txt
1,NYC
2,ABQ
3,CCC
4,DDD
Output:
Georgioss-MacBook-Pro:~ gsamaras$ g++ -Wall -std=c++0x main.cpp
Georgioss-MacBook-Pro:~ gsamaras$ ./a.out
ID = 1, name = NYC
ID = 2, name = ABQ
ID = 3, name = CCC
ID = 4, name = DDD

Using Structures and Pointers [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
This code is supposed to read in from a file and store the information. Here's the file:
5
Franks,Tom 2 3 8 3 6 3 5
Gates,Bill 8 8 3 0 8 2 0
Jordan,Michael 9 10 4 7 0 0 0
Bush,George 5 6 5 6 5 6 5
Heinke,Lonnie 7 3 8 7 2 5 7
right now I'm just focused on saving pointers to the names. Here's the code I have so far (Ignore the other functions I haven't gotten to those yet). I have to save the names using employees[row] = new Employee; and fin >> employees[row]->names; and I just don't know how to go about doing that.
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <vector>
using namespace std;
struct Employee {
string names;
vector<int> data;
int totalHrs;
};
int fillAndTotal(vector<Employee *>&employees);
void sort(vector<Employee *>&employees, int amount);
void output(vector<Employee *>&employees, int amount);
int main()
{
vector<Employee *>employees;
//vector<string>names;
int amount = 0;
amount = fillAndTotal(employees);
sort(employees, amount);
output(employees, amount);
system("pause");
return 0;
}
int fillAndTotal(vector<Employee *>&employees) {
int const TTL_HRS = 7;
ifstream fin;
fin.open("empdata.txt");
if (fin.fail()) {
cout << "ERROR";
}
int sum = 0;
int numOfNames;
fin >> numOfNames;
string tmpString;
int tempInt = 0;
vector<int>temp(8);
for (int row = 0; row < numOfNames; row++) {
employees[row] = new Employee;
fin >> employees[row]->names;
Firstly, you don't need pointers for this - your Employee structure is perfectly safe to store as-in in a vector.
Secondly, when reading line-orientated data like this, it's very easy to get off-track and let your reads overflow into the next line, or underflow and you not carry out enough reads for the line - what I do is write a function that reads a whole line at a time and returns a stringstream containing just that line, then I do my individual reads on that stringstream.
Thirdly, and finally, it's always useful to write functions that allows you to dump out your data structures so that you can confirm visually that you've populated the structures correctly. Or you can use a debugger.
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
struct Employee
{
std::string names;
std::vector<int> data;
int totalHrs;
};
using EmpList = std::vector<Employee>;
int fillAndTotal(EmpList& employees);
std::stringstream readRowData(std::istream& fin);
#ifndef NDEBUG
// Debug - dump to stream.
std::ostream& operator<<(std::ostream& out, const Employee& employee);
std::ostream& operator<<(std::ostream& out, const EmpList& employees);
#endif
int main(int argc, char* argv[])
{
EmpList employees;
auto grandTotal = fillAndTotal(employees);
std::cout << employees;
std::cout << "\nGrand total hours: " << grandTotal << std::endl;
}
int fillAndTotal(EmpList& employees)
{
auto fin = std::ifstream("empdata.txt");
auto rowCount = 0;
auto rowData = readRowData(fin);
rowData >> rowCount;
auto totalHours = 0;
for (auto i = 0; i < rowCount; ++i)
{
rowData = readRowData(fin);
if (!fin.eof())
{
auto employee = Employee{};
rowData >> employee.names;
int hours;
while (rowData >> hours)
{
if (hours != 0)
{
employee.data.push_back(hours);
employee.totalHrs += hours;
totalHours += hours;
}
}
employees.push_back(employee);
}
}
return totalHours;
}
std::stringstream readRowData(std::istream& fin)
{
std::stringstream rowStream;
std::string rowData;
if (getline(fin, rowData))
{
rowStream.str(rowData);
}
return rowStream;
}
#ifndef NDEBUG
std::ostream& operator<<(std::ostream& out, const Employee& employee)
{
out << "Name: " << employee.names << '\n';
out << "Total hours: " << employee.totalHrs << '\n';
out << "Individual hours:";
for (auto const &hours : employee.data)
{
out << ' ' << hours;
}
out << std::endl;
return out;
}
std::ostream& operator<<(std::ostream& out, const EmpList& employees)
{
auto first = true;
for (auto const &employee : employees)
{
if (first)
{
first = false;
}
else
{
out << '\n';
}
out << employee;
}
return out;
}
#endif
Now your output function is already written for you, and you just need to write your sort.

While Loop, Loops twice before cin.get() in c++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am trying to use cin.get() to pause a loop on every time around.
prodAtr.h:
#ifndef PRODATR
#define PRODATR
#include <array>
#include <vector>
#include <string>
extern std::array<std::string, 6> sProductType = { //Array contents here };
extern std::vector<std::vector<double>> nProductRates = {
{ //Array contents here },
{ //Array contents here },
{ //Array contents here },
{ //Array contents here },
{ //Array contents here },
{ //Array contents here }
};
#endif
Wholesale.cpp:
#include "stdafx.h"
#include <iostream>
#include "prodAtr.h"
int ShowProdOpt();
float GetCost();
void CalulateTiers(float, int);
int main()
{
using namespace std;
float fCost = GetCost();
cout << endl;
int nOptChoice = ShowProdOpt();
CalulateTiers(fCost, nOptChoice);
return 0;
}
int ShowProdOpt()
{
using namespace std;
cout << "Please select you product type: " << endl;
for (unsigned int i = 0; i < sProductType.size(); i++)
{
cout << "[" << i + 1 << "]" << sProductType[i] << " ";
}
cout << endl;
int nResult;
cin >> nResult;
return nResult;
}
float GetCost()
{
float fCost;
std::cout << "What is the cost? $";
std::cin >> fCost;
return fCost;
}
void CalulateTiers(float fCost, int nType)
{
using namespace std;
int iii = 0;
while(iii < 10)
{
int jjj = iii + 1;
float fPrice = floor(((nProductRates[nType - 1][iii] * fCost) + fCost) * 100 + 0.5) / 100;
cout << "Tier[" << jjj << "]: $" << fPrice << endl;
cin.get();
iii++;
}
}
VS 2013 log output (minus file loc info):
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
But my result is:
Tier[1]: $1.34
Tier[2]: $1.22
then cin.get() seems to pause and work properly from there.
How do I get cin.get() to pause after every execution of the loop?
I can't give a definitive answer because you have not provided more code, but it seems like there was already something in your cin buffer, so it took that in the get() and continued execution.
Try flushing the buffer before you enter the loop.
SEE: How do I flush the cin buffer?
Ok I added
cin.clear();
cin.ignore();
right before the while loop. Now it works as desired.

Taking integers out of a string C++ [duplicate]

This question already has answers here:
How to parse a string to an int in C++?
(17 answers)
c++ parse int from string [duplicate]
(5 answers)
Closed 8 years ago.
I wanted to know how I can grab numbers out of a string in C++. I'm getting the string from an input and will be getting multiple lines, but I already have the line reading working.
Note: the lines always have an even number of ints
Here's what I'd like the code to look something like:
std::getline(std::cin, line);// line looks something like "10 3 40 45 8 12"
int a, b;
while(!line.empty() /*line still has ints to extract*/) {
a = someMethod(line);//gets first int. So, 10 first loop, 40 second, 8 third
b = someMethod(line);//gets second int. So, 3 first loop, 45 second, 12 third
myMethod(a,b);//a method from elsewhere in my code. It's here so you know that I need both a and b
}
Anything similar would help. Thank you very much!
Here is a complete example.
#include <sstream>
#include <string>
#include <iostream>
int main(){
std::string line = "2 4 56 6";
std::stringstream stream(line);
int i;
while (stream >> i) {
std::cout << i << std::endl;
}
}
The following works fine also, so reading multiple lines should not be a problem.
#include <sstream>
#include <string>
#include <iostream>
int main(){
std::string line = "2 4 56 6";
std::stringstream stream(line);
int i;
while (stream >> i) {
std::cout << i << std::endl;
}
line = "32 62 44 6 22 58 34 60 71 86";
stream.clear();
stream.str(line);
int a,b;
while(stream >> a && stream >> b){
std::cout << a << " " << b << "\n";
}
}
Get tokens from string line and use them as you want.
#include <iostream>
#include <string>
#include <boost/tokenizer.hpp>
using namespace std;
typedef boost::tokenizer<boost::char_separator<char> >
tokenizer;
void myMethod(int a, int b)
{
cout<<a<<" "<<b<<endl;
}
void getNumber(string line)
{
boost::char_separator<char> sep(" ");
tokenizer tokens(line, sep);
string evenStr, oddStr;
for(tokenizer::iterator iterToken=tokens.begin();
iterToken != tokens.end(); ++iterToken)
{
evenStr = *iterToken;
++iterToken;
if(iterToken != tokens.end())
{
oddStr = *iterToken;
myMethod(atoi(evenStr.c_str()), atoi(oddStr.c_str()));
}
}
}
int main()
{
string line("10 3 40 45 8 12");
getNumber(line);
return 0;
}
You can do like this:
string line;
getline(std::cin, line);// line looks something like "10 3 40 45 8 12"
int a, b;
vector<string> tokens;
istringstream iss(line);
copy(istream_iterator<string>(iss),
istream_iterator<string>(),
back_inserter<vector<string> >(tokens));
stringstream s;
for (int i=0;i<tokens.size()/2;i++)
{
s<< tokens[i];
s>>a;
s.clear();
s<<tokens[i+2];
s>>b;
s.clear();
myMethod(a,b);
}
There are multiple ways to achieve this. I prefer to use boost.
Example:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
int main()
{
std::string line = "10 3 40 45 8 12 9"; //std::getline(std::cin, line);// line looks something like "10 3 40 45 8 12"
std::vector<std::string> intNumbers;
std::string s;
boost::split(intNumbers, line, boost::is_any_of(" "), boost::token_compress_on);
unsigned int i=0;
while(i < intNumbers.size())
{
try{
int a = boost::lexical_cast<int>(intNumbers[i++]);
if(i >= intNumbers.size())
{
std::cout << "invlaid values" << std::endl;
break;
}
int b = boost::lexical_cast<int>(intNumbers[i++]);
std::cout << "value a: " << a << std::endl;
std::cout << "value b: " << b << std::endl;
std::cout << "my method (multiply) a*b: " << (a*b) << std::endl;
}
catch(boost::bad_lexical_cast &e)
{
std::cout << "invlaid values" << std::endl;
}
}
}