Manipulators, C++ what order should I use them in? - c++

I am trying to learn about manipulators...is there a specific order for them?
For ex does std::setw come after or before std::setfill and should they be in separate lines?

There's no specific order, just make sure you include the <iomanip> library.
Example on your setw/setfil question:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
cout << setw(10) << setfill('*');
cout << 123;
}

There is not specific order. But please note this, for example, if you want to use std::left and std::right, or write everything in one line then things can get bit tricky.
For example this will not print expected output (prints just: 7
):
std::cout << std::setw(10) << std::left << 7 << std::setfill('x') << std::endl;
Because you need to set attributes first, then print whatever you want. So all three lines below will work, no matter their places change (prints: xxxxxxxxx7):
std::cout << std::setw(10) << std::setfill('x') << std::right << 7 << std::endl;
std::cout << std::right << std::setw(10) << std::setfill('x') << 7 << std::endl;
std::cout << std::setfill('x') << std::right << std::setw(10) << 7 << std::endl;
And the code below is just to clarify things.
#include <iostream>
#include <iomanip>
int main()
{
std::cout << std::setw(15) << std::setfill('-') << "PRODUCT" << std::setw(15) << std::setfill('-') << "AMOUNT" << std::endl;
std::cout << std::setw(15) << std::setfill('-') << "Brush" << std::setw(15) << std::setfill('-') << 10 << std::endl;
std::cout << std::setw(15) << std::setfill('-') << "Paste" << std::setw(15) << std::setfill('-') << 8 << std::endl << std::endl;
std::cout << std::setw(15) << std::left << std::setfill('-') << "PRODUCT" << std::setw(15) << std::left << std::setfill('-') << "AMOUNT" << std::endl;
std::cout << std::setw(15) << std::left << std::setfill('-') << "Brush" << std::setw(15) << std::left << std::setfill('-') << 10 << std::endl;
std::cout << std::setw(15) << std::left << std::setfill('-') << "Paste" << std::setw(15) << std::left << std::setfill('-') << 8 << std::endl << std::endl;
std::cout << std::setw(15) << std::right << std::setfill('-') << "PRODUCT" << std::setw(15) << std::right << std::setfill('-') << "AMOUNT" << std::endl;
std::cout << std::setw(15) << std::right << std::setfill('-') << "Brush" << std::setw(15) << std::right << std::setfill('-') << 10 << std::endl;
std::cout << std::setw(15) << std::right << std::setfill('-') << "Paste" << std::setw(15) << std::right << std::setfill('-') << 8 << std::endl << std::endl;
return 0;
}

Related

Move semantics in parameter passing

I have following test example:
#include <iostream>
#include <vector>
void foo (std::vector<int> value) {
std::cout << "value "
<< &value
<< " "
<< value.data()
<< " "
<< value.size()
<< std::endl;
}
void foo2 (std::vector<int>&& rvalure_ref) {
std::cout << "rvalue_ref "
<< &rvalure_ref
<< " "
<< rvalure_ref.data()
<< " "
<< rvalure_ref.size()
<< std::endl;
}
int main() {
std::vector<int> value(5, 0);
std::cout << "init "
<< &value
<< " "
<< value.data()
<< " "
<< value.size()
<< std::endl;
foo(std::move(value));
std::cout << "done "
<< &value
<< " "
<< value.data()
<< " "
<< value.size()
<< std::endl;
}
The result of the code above is:
init 0x7ffed27c6450 0x56480bc1eeb0 5
value 0x7ffed27c6470 0x56480bc1eeb0 5
done 0x7ffed27c6450 0 0
Looks great:
Now, move to:
#include <iostream>
#include <vector>
void foo (std::vector<int> value) {
std::cout << "value "
<< &value
<< " "
<< value.data()
<< " "
<< value.size()
<< std::endl;
}
void foo2 (std::vector<int>&& rvalure_ref) {
std::cout << "rvalue_ref "
<< &rvalure_ref
<< " "
<< rvalure_ref.data()
<< " "
<< rvalure_ref.size()
<< std::endl;
}
int main() {
std::vector<int> value(5, 0);
std::cout << "init "
<< &value
<< " "
<< value.data()
<< " "
<< value.size()
<< std::endl;
foo2(std::move(value));
std::cout << "done "
<< &value
<< " "
<< value.data()
<< " "
<< value.size()
<< std::endl;
}
The result is:
init 0x7ffccc93a5c0 0x56124b3a8eb0 5
rvalue_ref 0x7ffccc93a5c0 0x56124b3a8eb0 5
done 0x7ffccc93a5c0 0x56124b3a8eb0 5
My problem is:
For the 1st case, it is perfectly called by "move semantics", and as you see, the ownership of the vector has been transfered to the function parameter. Finally, at "done", the data is null to verify the the vector at main() no longer owns the vector.
Now to explicitly claim the parameter is "rvalue reference", as case 2. As you see, actually it is like "call by (l)reference".
How can I figure out it?

How to understand C++ std::setw 's inconsistent behaviour?

Given the following code:
/*Formatting Output
**Goal: practice using cout to format output to console
**Print the variables in three columns:
**Ints, Floats, Doubles
*/
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int a = 45;
float b = 45.323;
double c = 45.5468;
int aa = a + 9;
float bb = b + 9;
double cc = c + 9;
int aaa = aa + 9;
float bbb = bb + 9;
double ccc = cc + 9;
// 1st attempt :>
cout << "\n\n\n" << "// 1st attempt :>" << "\n";
cout << "12345678901234567890123456789012345678901234567890" << "\n";
cout << "Ints" << setw(15) << "Floats" << setw(15) << "Doubles" << "\n";
cout << a << setw(15) << b << setw(15) << c << "\n";
cout << aa << setw(15) << bb << setw(15) << cc << "\n";
cout << aaa << setw(15) << bbb << setw(15) << ccc << "\n";
// 2nd attempt :>
cout << "\n\n\n" << "// 2nd attempt :>" << "\n";
cout << "12345678901234567890123456789012345678901234567890" << "\n";
cout << std::left << std::setfill(' ') << std::setw(15) << "Ints" << setw(15) << "Floats" << setw(15) << "Doubles" << "\n";
cout << a << setw(15) << b << setw(15) << c << "\n";
cout << std::left << std::setfill(' ') << setw(15) << aa << setw(15) << bb << setw(15) << cc << "\n";
cout << aaa << setw(15) << bbb << setw(15) << ccc << "\n";
// 3rd attempt :>
cout << "\n\n\n" << "// 3rd attempt :>" << "\n";
cout << "12345678901234567890123456789012345678901234567890" << "\n";
cout << std::left << std::setfill(' ') << std::setw(15) << "Ints" << setw(15) << "Floats" << setw(15) << "Doubles" << "\n";
cout << std::left << std::setfill(' ') << std::setw(15) << a << setw(15) << b << setw(15) << c << "\n";
cout << std::left << std::setfill(' ') << std::setw(15) << aa << setw(15) << bb << setw(15) << cc << "\n";
cout << std::left << std::setfill(' ') << std::setw(15) << aaa << setw(15) << bbb << setw(15) << ccc << "\n";
cout << "12345678901234567890123456789012345678901234567890" << "\n";
cout << std::right << std::setfill(' ') << std::setw(15) << "Ints" << setw(15) << "Floats" << setw(15) << "Doubles" << "\n";
cout << std::right << std::setfill(' ') << std::setw(15) << a << setw(15) << b << setw(15) << c << "\n";
cout << std::right << std::setfill(' ') << std::setw(15) << aa << setw(15) << bb << setw(15) << cc << "\n";
cout << std::right << std::setfill(' ') << std::setw(15) << aaa << setw(15) << bbb << setw(15) << ccc << "\n";
return 0;
}
// https://repl.it/#Tredekka/Cpp-Understanding-stdsetw
... I get the following output:
gcc version 4.6.3
// 1st attempt :>
12345678901234567890123456789012345678901234567890
Ints Floats Doubles
45 45.323 45.5468
54 54.323 54.5468
63 63.323 63.5468
// 2nd attempt :>
12345678901234567890123456789012345678901234567890
Ints Floats Doubles
4545.323 45.5468
54 54.323 54.5468
6363.323 63.5468
// 3rd attempt :>
12345678901234567890123456789012345678901234567890
Ints Floats Doubles
45 45.323 45.5468
54 54.323 54.5468
63 63.323 63.5468
12345678901234567890123456789012345678901234567890
Ints Floats Doubles
45 45.323 45.5468
54 54.323 54.5468
63 63.323 63.5468
... note: I was intentionally "inconsistent" with the code, "because" I'm trying to understand the behavior of the <iomanip> && std::setw() code.
If you look at the output from the 1st attempt, you'll notice that the header row "string" output is offset from the data rows "numerical" output... and while it's "mostly" accomplishing the purpose of aligning things in columns, it's both not accurate and not consistent.
In the 2nd attempt, you'll see that I've discovered that if I prepend my row output with:
<< std::left << std::setfill(' ') << setw(15)
... then I get the row to look correctly (as seen in the header & 2nd data row) ... but now you'll notice that the 1st & 3rd data rows are very wrong:
4545.323 45.5468
...
6363.323 63.5468
... how does "using/executing" ...
<< std::left << std::setfill(' ') << setw(15)
... affect "future" executions of setw()?
For completeness' sake, I've shown in the 3rd Attempt that it's possible to correctly & accurately align columns of data (either left or right) using <iomanip> && std::setw() ... but why the inconsistencies?
(#WhozCraig's answer helped me get to where I am, but did not delve deep enough to help me understand either: (a) why it 'pseudo' works || (b) why after you make it work correctly the 'first' time, it then breaks the 'pseudo' functionality.)
Here's your issue: std::setw() doesn't act as a buffer, it modifies the way the next expression gets evaluated.
You need to understand the "range" that each of these expressions has. Specifically, std::setfill(int) and std::left/std::right change the default behaviour, and seem last until they are overwritten by another setfill() or std::left/std::right. std::setw(int) on the other hand seems to only affect whatever is passed right after it (which is weird, because I feel like I've also seen it behave like std::setfill and the others before)
So, to sum up, what you want is something more akin to this:
int a = 45;
float b = 45.323;
double c = 45.5468;
int aa = a + 9;
float bb = b + 9;
double cc = c + 9;
int aaa = aa + 9;
float bbb = bb + 9;
double ccc = cc + 9;
std::cout << std::endl << std::endl << std::endl;
std::cout << std::left << std::setfill('~');
// 1st attempt :>
std::cout << "// 1st attempt :>" << std::endl;
std::cout << "12345678901234567890123456789012345678901234567890" << std::endl;
std::cout << std::setw(10) << "Ints" << std::setw(10) << "Floats" << std::setw(10) << "Doubles" << std::endl;
std::cout << std::setw(10) << a << std::setw(10) << b << std::setw(10) << c << std::endl;
std::cout << std::setw(10) << aa << std::setw(10) << bb << std::setw(10) << cc << std::endl;
std::cout << std::setw(10) << aaa << std::setw(10) << bbb << std::setw(10) << ccc << std::endl;
std::cout << std::endl << std::endl << std::endl << std::setfill('*');
// 2nd attempt :>
std::cout << "// 2nd attempt :>" << std::endl;
std::cout << "12345678901234567890123456789012345678901234567890" << std::endl;
std::cout << std::setw(10) << "Ints" << std::setw(10) << "Floats" << std::setw(10) << "Doubles" << std::endl;
std::cout << std::setw(10) << a << std::setw(10) << b << std::setw(10) << c << std::endl;
std::cout << std::setw(10) << aa << std::setw(10) << bb << std::setw(10) << cc << std::endl;
std::cout << std::setw(10) << aaa << std::setw(10) << bbb << std::setw(10) << ccc << std::endl;
std::cout << std::endl << std::endl << std::endl;
// 3rd attempt :>
std::cout << "// 3rd attempt :>" << std::endl;
std::cout << "12345678901234567890123456789012345678901234567890" << std::endl;
std::cout << std::setw(10) << "Ints" << std::setw(10) << "Floats" << std::setw(10) << "Doubles" << std::endl;
std::cout << std::setw(10) << a << std::setw(10) << b << std::setw(10) << c << std::endl;
std::cout << std::setw(10) << aa << std::setw(10) << bb << std::setw(10) << cc << std::endl;
std::cout << std::setw(10) << aaa << std::setw(10) << bbb << std::setw(10) << ccc << std::endl;
std::cout << "12345678901234567890123456789012345678901234567890" << std::endl;
std::cout << std::right << std::setfill(' ');
std::cout << std::setw(10) << "Ints" << std::setw(10) << "Floats" << std::setw(10) << "Doubles" << std::endl;
std::cout << std::setw(10) << a << std::setw(10) << b << std::setw(10) << c << std::endl;
std::cout << std::setw(10) << aa << std::setw(10) << bb << std::setw(10) << cc << std::endl;
std::cout << std::setw(10) << aaa << std::setw(10) << bbb << std::setw(10) << ccc << std::endl;
std::cout << std::endl << std::endl << std::endl;
(You'll notice I also changed "\n" to std::endl which additionally flushes the buffer after each line.)

Scenario output gives wrong answer upon second loop

I'm pretty much done with this program except for this small problem.
The problem is when the first time I loop through the program with the following in put of 20.0 36.0 72.0 2.0 10.0 18.0 10.0 my output comes out to be 232.59 sec which is correct.
For the second time I loop around, I input 25.0 72.0 200.0 1.5 8.0 30.0 20.0 my output comes out to be 800.41 which is wrong when it should be 1141.63
Now if I reverse the inputs and take what I entered for the second loop for the first loop and first for the second loop. I do get my output of 1141.63 for the first loop, but the second loop, my answer is 1141.63 . I am very puzzled as to how this happening. One of my early solutions was to reset all variables back to 0 after each loop using another function, but that didn't seem to work and now I'm here.
EDIT: Problem figured out. Had to reset time and volFilled to 0 at the end of each loop.
void Well::timeReq()
{
bool exit = false;
while (!exit)
{
std::cout << "Enter 7 digits to evaluate or type 0 now to exit." << std::endl;
std::cin >> UP;
if (UP == 0)
{
exit = true;
break;
}
std::cin >> D >> L >> B >> P >> DOWN >> V;
double WL = L;
double radius = (D / 2);
while (volFilled < V)
{
time += UP;
time += sqrt(2 * (L) / (acceleration * 12.0));
time += (L) / (P);
L += (B * cuIns) / (pi*pow(radius, 2));
time += DOWN;
volFilled += B;
}
std::cout << std::endl;
std::cout << "Scenario " << scenario << ":" << std::endl;
std::cout << std::left << std::setw(25) << "\tUp Hill" << std::left << std::setw(30) << std::fixed << std::setprecision(2)
<< UP << " sec" << std::endl;
std::cout << std::left << std::setw(25) << "\tWell Diamter" << std::left << std::setw(30) << std::fixed << std::setprecision(2)
<< D << " in" << std::endl;
std::cout << std::left << std::setw(25) << "\tWater Level" << std::left << std::setw(30) << std::fixed << std::setprecision(2)
<< WL << " in" << std::endl;
std::cout << std::left << std::setw(25) << "\tBucket Volume" << std::left << std::setw(30) << std::fixed << std::setprecision(2)
<< B << " cu ft" << std::endl;
std::cout << std::left << std::setw(25) << "\tBucket Ascent Rate" << std::left << std::setw(30) << std::fixed << std::setprecision(2)
<< P << " in/sec" << std::endl;
std::cout << std::left << std::setw(25) << "\tDownhill" << std::left << std::setw(30) << std::fixed << std::setprecision(2)
<< DOWN << " sec" << std::endl;
std::cout << std::left << std::setw(25) << "\tRequired Volume" << std::left << std::setw(30) << std::fixed << std::setprecision(2)
<< V << " cu ft" << std::endl;
std::cout << std::left << std::setw(25) << "\tTIME REQUIRED" << std::left << std::setw(30) << std::fixed << std::setprecision(2)
<< time << " sec" << std::endl;
scenario++;
}
}
While this may not completely fix your issue, you need to at least reinitialize your volFilled value back to 0.0 between scenarios. Otherwise you're just continuing from the previous scenario's volFilled, and that explains why the second test that you did with switching the scenarios yielded the same output. After the first scenario where volFilled reaches 20.0, it won't execute the logic inside the considion while (volFilled < V) in the second scenario because at this point, volFilled = 20 while V = 10.

Generating a new guid string in c++ missing some zeros

I tried using the following code to generate a new guid string of 36 characters, but this sometimes prints only 35 or 34 characters. I suppose this is due to the 'zeros' in the guid, but I am unable to clearly see why. Is there a way I can correct this issue?
#include <string>
#include <sstream>
#include <iostream>
#include <windows.h>
#include <iomanip>
int main()
{
GUID guid;
CoCreateGuid(&guid);
std::ostringstream os;
os.width(8);
os << std::hex << std::setfill('0') << guid.Data1 << '-';
os.width(4);
os << std::hex << std::setfill('0') << guid.Data2 << '-';
os.width(4);
os << std::hex << std::setfill('0') << guid.Data3 << '-';
os.width(2);
os << std::hex << std::setfill('0')
<< static_cast<short>(guid.Data4[0])
<< static_cast<short>(guid.Data4[1])
<< '-'
<< static_cast<short>(guid.Data4[2])
<< static_cast<short>(guid.Data4[3])
<< static_cast<short>(guid.Data4[4])
<< static_cast<short>(guid.Data4[5])
<< static_cast<short>(guid.Data4[6])
<< static_cast<short>(guid.Data4[7]);
std::string s(os.str());
std::cout << s << std::endl;
std::cout << s.length() << std::endl;
}
Sample output:
f6979589-b13c-416d-bf49-1497d99cd88
35
Press any key to continue . . .
You need to directly set field size for any new value you output, like this:
int main()
{
GUID guid;
CoCreateGuid(&guid);
std::ostringstream os;
os.width(8);
os << std::hex << std::setfill('0') << guid.Data1 << '-';
os.width(4);
os << std::hex << std::setfill('0') << guid.Data2 << '-';
os.width(4);
os << std::hex << std::setfill('0') << guid.Data3 << '-';
os.width(2);
os << std::hex << std::setfill('0') << std::setw(2)
<< static_cast<short>(guid.Data4[0]) << std::setw(2)
<< static_cast<short>(guid.Data4[1])
<< '-' << std::setw(2)
<< static_cast<short>(guid.Data4[2]) << std::setw(2)
<< static_cast<short>(guid.Data4[3]) << std::setw(2)
<< static_cast<short>(guid.Data4[4]) << std::setw(2)
<< static_cast<short>(guid.Data4[5]) << std::setw(2)
<< static_cast<short>(guid.Data4[6]) << std::setw(2)
<< static_cast<short>(guid.Data4[7]);
std::string s(os.str());
std::cout << s << std::endl;
std::cout << s.length() << std::endl;
}

Formatting Cout Output in C++

This is the expected output:
COUNT | WORD
------+------
1 | .3
1 | .3.4
1 | 3
2 | 12.34
1 | test1.12.34
3 | this
This is my proper code:
std::cout << "COUNT | WORD" << '\n';
std::cout << "------+------" << '\n';
std::cout << std::setw(4) << "1" << std::setw(3) << '|' << std::setw(3) << ".3" << '\n';
std::cout << std::setw(4) << "1" << std::setw(3) << '|' << std::setw(3) << ".3.4" << '\n';
std::cout << std::setw(4) << "1" << std::setw(3) << '|' << std::setw(3) << "3" << '\n';
std::cout << std::setw(4) << "2" << std::setw(3) << '|' << std::setw(3) << "12.34" << '\n';
std::cout << std::setw(4) << "1" << std::setw(3) << '|' << std::setw(3) << "test1.12.34" << '\n';
std::cout << std::setw(4) << "3" << std::setw(3) << '|' << std::setw(3) << "this" << '\n';
Unfortunately, my ouput's messy the WORD
COUNT | WORD
------+------
1 | .3
1 |.3.4
1 | 3
2 |12.34
1 |test1.12.34
2 |this
Could anyone suggest me a solution for that. Thanks
Instead of having
std::cout << std::setw(4) << "1" << std::setw(3) << '|' << std::setw(3) << ".3" << '\n';
For each line, add a space after the '|' character:
std::cout << std::setw(4) << "1" << std::setw(3) << "| " << std::setw(3) << ".3" << '\n';
Why not this ::
std::cout << "COUNT | WORD" << '\n';
std::cout << "------+------" << '\n';
std::cout << std::setw(4) << "1" << std::setw(3) << '|' << ' ' << ".3" << '\n';
std::cout << std::setw(4) << "1" << std::setw(3) << '|' << ' ' << ".3.4" << '\n';
std::cout << std::setw(4) << "1" << std::setw(3) << '|' << ' ' << "3" << '\n';
std::cout << std::setw(4) << "2" << std::setw(3) << '|' << ' ' << "12.34" << '\n';
std::cout << std::setw(4) << "1" << std::setw(3) << '|' << ' ' << "test1.12.34" << '\n';
std::cout << std::setw(4) << "3" << std::setw(3) << '|' << ' ' << "this" << '\n';
Doing this will set the left hand side filler character.
cout.fill('-');
cout.width(40);
cout<< "LINE1" <<endl;
cout.fill('-');
cout.width(40);
cout<< 3 <<endl;
cout.fill('-');
cout.width(40);
cout<< 3.4 <<endl;
cout.fill('-');
cout.width(40);
cout<< "TEST " << 12.34 <<endl;