c++ vector iterator output display vertically in columns

c++ vector iterator output display vertically in columns



I am trying to output my strings column-wise using the vector iterator as shown in the attached image.
For now I am just displaying a test case using the names and the cider order after which I want to replicate the same for others. Desired output screenshot



Below is my current code:


// values for controlling format
const int name_width = 15 ;
const int int_width = 7 ;
const int dbl_width = 12 ;
const int num_flds = 7 ;
const std::string sep = " |" ;
auto total_width = name_width*2 + int_width*2 + dbl_width*3 + sep.size() * num_flds ;
const std::string line = sep + std::string( total_width-1, '-' ) + '|' ;

cout<<"How many people ordered? ";
cin>>odrs; // Store number of orders

for(int i=1; i<=odrs; i++)
cout<<"Enter the name of person #"<<i<<":"<<endl;;
cin>>names; // Store names of users

odrNames.push_back(names); // Store names as entered as

cout<<"How many orders of cider did "<<names<<" have? ";
cout<<endl;
cin>>odrciderjuice; // Store Cider order item
sbCider = odrciderjuice * 5.5; // Calculate Cider order per price
odrCider.push_back(odrciderjuice); // Store Cider order item based on entry
SbCider.push_back(sbCider); // Store calculated Cider order per price

cout<<"How many orders of apple juice did "<<names<<" have? ";
cout<<endl;
cin>>odrapplejuice; // Store Juice order item
sbJuice = odrapplejuice * 4.5; // Calculate Juice order per price
odrApple.push_back(odrapplejuice); // Store Juice order item based on entry
SbJuice.push_back(sbJuice); // Store calculated Juice order per price
cout<<endl;

total = sbCider + sbJuice; // Calculate total between Cider and Juice
GTotal.push_back(total); // Store total values after calculation
cout<<endl;


for(vector<string>::iterator naming = odrNames.begin(); naming!= odrNames.end(); ++naming)
cout << sep << std::setw(name_width) << *naming<<"v";

for(vector<int>::iterator ciderOdr = odrCider.begin(); ciderOdr!= odrCider.end(); ++ciderOdr)
cout <<*ciderOdr;





Consider storing each order in a struct or class and then store instances of that object in your vector. Once you have that it's much simpler to format each line.
– Retired Ninja
Aug 22 at 1:17




2 Answers
2



Using iterator is indeed the idiomatic way to browse a collection. Simply, you need a collection of objects, instead of a bunch of unrelated collections!



In addition, you should be more consistent in your names, and only capitalizing a name between a single value and its collection is a future maintenance nightmare...



C++ is an OO language, and OO programming is a way to split a complex program in smaller units (the classes), which are responsable for only one small part of a larger program. This is intended to lead to code that is both simpler to test and to maintain.



Here the Order class could contain:


Order



As your formatting is not trivial, I would use an alternate class to handle it. That class would contain:


vector<Order>


ostream



The main would then simply contain code to load the orders.



Code could be:


#include <iostream>
#include <string>
#include <vector>
#include <iomanip>

using namespace std;

struct Order
static constexpr double ciderPrice = 5.5;
static constexpr double juicePrice = 4.5;
std::string name;
int cider;
int juice;

double sbCider() const
return cider * ciderPrice;

double sbJuice() const
return juice * juicePrice;

double total() const
return sbCider() + sbJuice();

;

class Bill
// values for controlling format
static const int name_width = 10 ;
static const int int_width = 6 ;
static const int dbl_width = 17 ;

const std::vector<Order>& orders;
std::ostream& out;

...

public:
Bill(const std::vector<Order>& orders, std::ostream& out):orders(orders),out(out)
Bill& show_line()
...
return *this;

Bill& show_header()
...
return *this;

Bill& show_order(const Order &order)
...
return *this

Bill& show_total()
return *this

Bill &show_average()
...
return *this;

Bill& show()
...
show_header().show_line();
for (const Order& order: orders)
show_order(order);

return show_line().show_total().show_average().show_line();

;
int main()
Order order;
vector<Order> orders;

int odrs;

cout<<"How many people ordered? ";
cin>>odrs; // Store number of orders

for(int i=1; i<=odrs; i++)
cout<<"Enter the name of person #"<<i<<":"<<endl;;
cin>>order.name; // Store names of users

cout<<"How many orders of cider did "<<order.name<<" have? "<<endl;
cin>>order.cider; // Store Cider order item

cout<<"How many orders of apple juice did "<<order.name<<" have? "<<endl;
cin>>order.juice; // Store Juice order item
orders.push_back(order);


Bill bill(orders, std::cout);
bill.show();
return 0;





Many thanks Serge for the input. However, i am getting some errors when i try to run your code: 1. the Contructor Bill gives the error Expected member name or ';' after declaration 2. No matching constructor for initialization of Bill
– Nii1
Aug 22 at 23:17






@Nii1: the ... are markers that the Bill class is not complete. This code only intends to show you how you could change the general design, but it is not working code.
– Serge Ballesta
Aug 23 at 7:57


Bill



After determining the length of each vector and ensuring they are the same length, simply use a regular for loop with an integer index. Then use that index to retrieve an element from each vector in turn.






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)