1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
|
#include <array>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <limits>
#include <string>
struct Date {
int month {};
int day {};
int year {};
friend bool operator<(const Date& lhs, const Date& rhs)
{
if(lhs.year < rhs.year) { return true; }
if(lhs.year > rhs.year) { return false; }
if(lhs.month < rhs.month) { return true; }
if(lhs.month > rhs.month) { return false; }
if(lhs.day < rhs.day) { return true; }
else { return false; }
}
friend std::istream& operator>>(std::istream& is, Date& rhs)
{
char c {};
is >> rhs.month >> c >> rhs.day >> c >> rhs.year;
return is;
}
friend std::ostream& operator<<(std::ostream& os, const Date& rhs)
{
return os << rhs.month << '/' << rhs.day << '/' << rhs.year;
}
};
struct Measurements {
int num1 {};
int num2 {};
int num3 {};
friend std::istream& operator>>(std::istream& is, Measurements& rhs)
{
char c {};
is >> rhs.num1 >> c >> rhs.num2 >> c >> rhs.num3;
return is;
}
friend std::ostream& operator<<(std::ostream& os, const Measurements& rhs)
{
return os << rhs.num1 << 'x' << rhs.num2 << 'x' << rhs.num3;
}
};
struct Shipment {
std::string name;
Date expiry;
Measurements sides;
int weight {};
std::string storage_method;
Date receive_date;
double item_price {};
friend bool operator<(const Shipment& lhs, const Shipment& rhs)
{
return lhs.receive_date < rhs.receive_date;
}
friend std::istream& operator>>(std::istream& is, Shipment& rhs)
{
is >> rhs.name >> rhs.expiry >> rhs.sides >> rhs.weight
>> rhs.storage_method >> rhs.receive_date >> rhs.item_price;
return is;
}
friend std::ostream& operator<<(std::ostream& os, const Shipment& rhs)
{
os << rhs.name << ": expiry date: " << rhs.expiry
<< "; box: " << rhs.sides
<< "; weight: " << rhs.weight
<< "; st. method: " << rhs.storage_method
<< "; received: " << rhs.receive_date
<< "; price: $" << std::fixed << std::setprecision(2)
<< rhs.item_price;
return os;
}
};
int readShipments(const std::string& filename, Shipment*& shipinfo);
unsigned readFileNumLines(std::ifstream& file);
int readDataIntoArray(std::ifstream& file, Shipment* shipinfo);
bool sortShipments(Shipment*& shipinfo, size_t howmany);
void waitForEnter();
int main()
{
Shipment* ship_stuff;
size_t ship_stuff_size {};
{
int check = readShipments("Shipments.txt", ship_stuff);
if(check < 0) { // there must be some errors
if(check == -1) { /* file error - exit */ }
else { /* unmanaged error - exit */}
} else if(check == 0) { /* empty file - exit */
} else /* 0 < check */{ ship_stuff_size = static_cast<size_t>(check); }
} // 'check' goes out of scope here
std::cout << "Before sorting:\n";
for(size_t i {}; i<ship_stuff_size; ++i) {
std::cout << ship_stuff[i] << '\n';
}
sortShipments(ship_stuff, ship_stuff_size);
std::cout << "\nAfter sorting:\n";
for(size_t i {}; i<ship_stuff_size; ++i) {
std::cout << ship_stuff[i] << '\n';
}
waitForEnter();
return 0;
}
// Read data from the file 'filename' into 'shipinfo'.
// Returns: 'shipinfo' new size if file read (it could be different from number
// of lines actually read);
// -1 if file can't be opened;
// 0 if file empty
int readShipments(const std::string& filename, Shipment*& shipinfo)
{
std::ifstream in(filename);
if(!in) {
std::cout << "Can't open " << filename << '\n';
return -1;
}
unsigned numlines = readFileNumLines(in);
if(!numlines) {
std::cout << "No data to be read inside " << filename << '\n';
return 0;
}
// Allocate enough memory for all the lines:
shipinfo = new Shipment[numlines] {};
readDataIntoArray(in, shipinfo);
in.close();
return numlines;
}
unsigned readFileNumLines(std::ifstream& file)
{
file.seekg(0, std::ios::beg);
unsigned count {};
for(std::string line; std::getline(file, line); ++count) {}
file.clear(); // restore file form EOF
file.seekg(0, std::ios::beg);
return count;
}
int readDataIntoArray(std::ifstream& file, Shipment* shipinfo)
{
int i {};
for(std::string line; std::getline(file, line); ++i) {
std::istringstream ss(line);
// File format:
// 1) Name of item
// 2) Expiry date
// 3) Box size in inches
// 4) Box weight
// 5) Storage method (R)
// 6) Date received
// 7) Item price
// Ex. Donuts 01:30:2015 10:11:12 20 R 01:21:2015 12.00
// name expiry sides weig sm received price
ss >> shipinfo[i];
}
return i;
}
bool sortShipments(Shipment*& shipinfo, size_t howmany)
{
if(howmany == 0) { return false; }
bool flag { true };
for(size_t i {1}; i<howmany && flag; ++i) {
flag = false;
for(size_t j {}; j<(howmany-1); ++j) {
if(shipinfo[j] < shipinfo[j+1]) {
// We currently rely on default copy assignment
Shipment temp = shipinfo[j];
shipinfo[j] = shipinfo[j+1];
shipinfo[j+1] = temp;
flag = true;
}
}
}
return true;
}
void waitForEnter()
{
std::cout << "\nPress ENTER to continue...\n";
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
|