C++列,完美排列
C++ columns, line up perfectly
所以我正在尝试编写这段代码,以完美的列显示 ASCII 代码,但列完全排列。我做错了什么?
#include <iostream> // cout
#include <iomanip> // setw
using namespace std;
int main ()
{
int a;
for(a=32;a<=255;++a)
{
cout << a << setw(2) <<static_cast<char>(a)<< setw(20);
}
return 0;
}
这就是我希望它的样子, http://www.asciitable.com/index/extend.gif
这会有点长,所以...工作代码在底部,它之前的所有内容都是解释。
-
列:在同一行中包含 n 列的一种简单方法是在每n个条目后有条件地插入换行符。 最简单的方法是使用模算术,将第一个条目视为
1
,并检查除以n时的余数是否0
。const int NUMBER_OF_COLUMNS = 5; // ... for(a=32;a<=255;++a) { cout << /* output... */ << ((a - 31) % NUMBER_OF_COLUMNS == 0 ? "n" : ""); }
工作原理:我们从循环中加减,将其视为从 1 开始(在这种情况下,通过减去 31,因为它从 32 开始),然后在该值上使用模来确定它是否可以被n整除。 如果是,我们插入
"n"
(换行符);如果不是,我们插入""
(什么都没有)。这也可以修改为始终在循环结束时输出换行符,而无需将
cout << endl;
或cout << 'n';
放在循环外部。// Change... << ((a - 31) % NUMBER_OF_COLUMNS == 0 ? "n" : ""); // To... << ((a - 31) % NUMBER_OF_COLUMNS == 0 || a == 255 ? "n" : ""); // Inserts "n" every n columns, OR when a is 255.
或者,您可以将检查放在输出的开头,并将循环的计数器视为以 0 开头;在这种情况下,我们将减去 32。
const int NUMBER_OF_COLUMNS = 5; // ... for(a=32;a<=255;++a) { cout << ((a - 32) % NUMBER_OF_COLUMNS == 0 ? "n" : "") << /* output... */; }
这会在输出的最开头放置一个换行符,尽管如果不需要这样做,可以通过专门检查
a
实际上不是其起始值来避免。// Change... ((a - 32) % NUMBER_OF_COLUMNS == 0 ? "n" : "") // To... ((a - 32) % NUMBER_OF_COLUMNS == 0 && a != 32 ? "n" : "") // Inserts "n" every n columns, unless a is 32.
如果需要,还可以修改此方法,让用户指定要显示的列数。
-
间距:如果传递
std::setw()
常量值,则可能会在某些位置弄乱格式。 就目前而言,间距有两个问题。for(a=32;a<=255;++a) { cout << a << setw(2) // Doesn't take into account the number of digits in a. <<static_cast<char>(a) << setw(20); // Doesn't take into account character 127 not being a graphical // character. }
作为替代方法,您可以使用
t
输出选项卡,更改应用std::setw()
的输出,或使用一些逻辑来确定要传递std::setw()
的值。如果宽度是常量,则第一个将无法正确排列。 这是因为
std::setw()
会影响它后面的下一个输出,而强制转换为char
保证此输出始终只有一个字符(因此,如果指定宽度x,它将填充x- 1 个空格)。 有两种方法可以解决这个问题:在输出a
之前使用std::setw()
和std::left
...cout << setw(4) << left // Tells cout to make sure a is at least 4 characters, // padding it at the end if necessary. // 4 characters are used to account for 3 digits + a space. << a << /* output... */;
或者像您目前一样将
std::setw()
应用于static_cast<char>(a)
,但使用一些逻辑来确定值......cout << a << setw(a < 100 ? 3 : 2) // Set width to 3 if a < 100, or 2 otherwise. << static_cast<char>(a) << /* output... */;
如果我们使用第一个,最好将
std::left
移到循环之外,如下所示:cout << left; for(a=32;a<=255;++a) { cout << setw(4) << /* output.. */; } cout << right; // Reset to default.
由于我们没有在循环内传递
std::right
或std::internal
,因此没有理由每次都传递std::left
。在某些平台上,字符 127 会破坏它后面所有内容的格式,直到行尾;这是因为它实际上不是一个图形字符,因此实际上不会显示(Unicode 有"DEL",而 Win32 控制台字体有一个房子,所以它们可以以图形方式显示它)。 解决此问题的最简单方法是在
static_cast<char>(a)
之后输出一个或多个制表位或t
秒。cout << /* output... */ << static_cast<char>(a) << "tt" << /* output... */;
-
等等,那
?:
是什么?:这将是条件运算符,非正式地称为"三元运算符"。 此运算符接受 3 个操作数,其作用类似于可用作表达式的微型if ... else
语句。 它用作:条件
?
真结果:
假结果条件被转换为
bool
,并且可以是任何可以计算为布尔值的东西。 如果true
,则运算符计算结果为真;如果false
,则计算结果为假结果。 这个运算符看起来有点奇怪,但非常有用,因为它允许在无法使用if
语句的情况下应用条件逻辑(例如在变量赋值期间)。在这里,我使用了两次:
- 要有条件地在每n列之后插入一个换行符到
std::cout
中。 请注意,它括在括号中;这是因为它的优先级低于<<
运算符。 它的计算结果为"n"
或空字符串""
,具体取决于a
的值。 - 要确定要传递的值
std::setw()
,如果它应用于static_cast<char>(a)
而不是a
。 如果a
小于 100,则计算结果为 3,否则2
计算结果。
- 要有条件地在每n列之后插入一个换行符到
因此,结合这些,我们得到的最终结果如下所示:
#include <iostream> // cout
#include <iomanip> // setw, left, right
using namespace std;
int main ()
{
const int NUMBER_OF_COLUMNS = 8; // Number of columns per line.
cout << left; // Append padding after output.
int a;
for(a=32;a<=255;++a)
{
cout << setw(4) // Pad until 4 characters.
<< a
<< static_cast<char>(a)
<< "tt" // Use tabs for spacing.
<< ((a - 31) % NUMBER_OF_COLUMNS == 0 || a == 255 ? "n" : "");
// Insert newline when specified, and after outputting the last entry.
}
// This isn't necessary since you exit right after, but it's a useful habit to develop
// if you format text for console output frequently.
// Remove if desired.
cout << right; // Reset to default.
return 0;
}
我还建议:
1)将using namespace std;
移动到main()
本身,和/或将其替换为:using std::cout; using std::left; using std::right; using std::setw;
2)在for
循环的条件内声明a
,如for(int a=32;a<=255;++1)
。
试试这个:
#include <iostream> // cout
#include <iomanip> // setw
using namespace std;
int main()
{
int a;
int count = 0;
for (a = 32; a <= 255; ++a)
{
cout << a << setw(2) << static_cast<char>(a);
if (count != 3)
{
cout << setw(20);
count++;
}
else
{
count = 0;
cout << endl;
}
}
cout << endl;
return 0;
}
PS:如果您想拥有更多同样长的列,请尝试将此if (count != 3)
和此cout << setw(20);
更改为类似if (count != 6)
和cout << setw(9);
我认为您正在寻找这样的东西:
#include <iostream> // cout
#include <iomanip> // setw
using namespace std;
int main ()
{
int a;
for(a=32;a<=255;++a)
{
cout << setw(3) << a << setw(20) <<static_cast<char>(a) << std::endl;
}
return 0;
}
setw(3)
在字符之前,您想要 3 而不是评论中提到的 2。 而且您还忘记在末尾打印换行符。
要获取看起来像链接的内容,您可以执行以下操作:
#include <iostream> // cout
#include <iomanip> // setw
using namespace std;
int main ()
{
int a;
int nColumns = 14;
for(a=32;a<=255;++a)
{
cout << setw(10) << a << setw(8) <<static_cast<char>(a);
if((a-31)%nColumns == 0)
{
cout<<endl;
}
}
return 0;
}
我的在线编译器不显示从 130 到 255 的字符,因此会出现中断(列在 130 之后不对齐)。如果您的字符可以正确显示每个字符,则不应看到任何中断。
例
如前所述,在输出值之前,您需要向std::cout
询问正确的宽度,并且当您有一定数量的列时,您需要有一种输出新行的方法。所以这里只是对代码的一个小编辑(这将使行中的数字增加,如果您希望值在列而不是行中增加,您需要做更多的数学运算,或者而不是直接输出值,将它们附加到每行的字符串中,然后在末尾输出值。我将在此答案的末尾添加第一个解决方案,因为行增量答案已经由其他人给出:-)):
#include <iostream>
#include <iomanip>
using namespace std;
int main ()
{
int nocols = 5; // number of columns that you want
for (int a = 32; a < 256; ++a)
{
cout << setw(3) << a << setw(20) << static_cast<char>(a);
if (!((a - 31) % nocols))
cout << endl;
}
return 0;
}
以下是列增量格式:
int nocols = 8; // number of columns that you want
int norows = 1 + (256 - 32 - 1) / nocols; // number of rows
for (int row = 0; row < norows; ++row)
{
for (int col = 0; col < nocols; ++col)
{
int ch = 32 + norows * col + row;
if (ch < 256)
cout << setw(3) << ch << setw(10) << static_cast<char>(ch) << ' ';
}
cout << endl;
}
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- 为什么不;名字在地图上是按顺序排列的吗
- 试试完美的正方形,你能给点小费吗
- C++优先级队列,按对象的唯一指针的特定方法升序排列
- 按对象的特定方法按升序排列的C++优先级队列
- 求出有多少个数字是完美平方,而sqrt()是L,R范围内的素数
- 不计算一个范围内的完美数
- 找到具有最多子串栅栏的字符串排列
- 完美前进使用 std::forward vs RefRefCast
- 重新排列单线以形成闭合多边形?
- 如何编写一个完美的缩写函数模板?
- 在数组中输入 n 个整数的列表,并以类似于钟摆来回移动的方式排列它们. 输入-1 3 2 5 4,输出5 3 1 2 4
- 将函数参数完美转发到函数指针:按值传递呢?
- 输入的 C++ 排列
- 公共/私有/受保护是否会更改内存中结构的排列?
- 如何在 C/C++ 中生成具有 n 组 5 个值(重复项)的所有可能排列的矩阵
- 在向量C++中排列奇数和偶数
- 如何进行排列?
- C++20理念:要求表达和完美转发
- C++列,完美排列