给定以下代码:
/*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 << "nnn" << "// 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 << "nnn" << "// 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 << "nnn" << "// 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
。我得到以下输出:
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
。注意:我故意与代码"不一致","因为"我试图理解<iomanip>
&std::setw()
代码的行为。
如果您查看第一次尝试的输出,您会注意到标题行"字符串"输出与数据行"数字"输出偏移... 虽然它"大部分"实现了在列中对齐内容的目的,但它既不准确也不一致。
在第二次尝试中,您将看到我发现如果我在行输出前面加上以下内容:
<< std::left << std::setfill(' ') << setw(15)
。然后我让行看起来正确(如标题和第二个数据行所示)......但是现在你会注意到第1和第3数据行是非常错误的:
4545.323 45.5468
...
6363.323 63.5468
。如何"使用/执行"...
<< std::left << std::setfill(' ') << setw(15)
。影响setw()
的"未来"执行?
为了完整起见,我在第三次尝试中表明,可以使用<iomanip>
&&std::setw()
正确准确地对齐数据列(左或右)。但为什么会出现不一致呢?
(@WhozCraig的回答帮助我到达了我的位置,但没有深入研究到足以帮助我理解:(a)为什么它是"伪"有效的||(b) 为什么在你让它在"第一次"正常工作后,它会破坏"伪"功能。
这是您的问题:std::setw()
不充当缓冲区,它会修改下一个表达式的计算方式。
您需要了解每个表达式的"范围"。具体来说,std::setfill(int)
和std::left
/std::right
更改默认行为,并且似乎一直持续到它们被另一个setfill()
或std::left
/std::right
覆盖为止。 另一方面,std::setw(int)
似乎只影响它之后传递的任何内容(这很奇怪,因为我觉得我以前也见过它的行为像std::setfill
和其他人)
所以,总结一下,你想要的更类似于这样:
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;
(您会注意到我还"n"
更改为std::endl
,这会在每行之后额外刷新缓冲区。