所以我试图编写这个代码,在完美的列中显示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
答案 0 :(得分:2)
这将会有点长,所以...工作代码位于底部,之前的所有内容都是一个解释。
列:在同一行中包含 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
实际上是否为起始值来避免。 / p>
// 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个空格填充。有两种方法可以解决此问题:在输出std::setw()
之前使用std::left
和a
...
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有&#34; DEL&#34;和Win32控制台字体有一个房子,所以他们可以显示它以图形方式)。解决此问题的最简单方法是在\t
之后输出一个或多个制表位或static_cast<char>(a)
。
cout << /* output... */
<< static_cast<char>(a)
<< "\t\t"
<< /* output... */;
Wait, what's that ?:
thing? :这将是conditional operator,非官方称为&#34;三元运算符&#34;。 This operator takes 3 operands, and acts like a miniature if ... else
statement that can be used as an expression。它用作:
条件 ?
true-result :
false-result
条件转换为bool
,可以是任何可以计算为布尔值的值。如果true
,则运算符求值为 true-result ;如果false
,则评估为 false-result 。这个运算符看起来有点奇怪,但非常有用,因为它允许在不能使用if
语句的情况下应用条件逻辑(例如在变量赋值期间)。
在这里,我使用了两次:
std::cout
。请注意,它括在括号中;这是因为it has lower precedence than the <<
operator。它评估为"\n"
或空字符串""
,具体取决于a
的值。std::setw()
的值,如果它已应用于static_cast<char>(a)
而不是a
。如果a
小于100,则评估为3,否则为2
。因此,结合这些,我们得到的结果如下:
#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)
<< "\t\t" // 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)在a
循环条件中声明for
为for(int a=32;a<=255;++1)
。
答案 1 :(得分:0)
试试这个:
#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);
答案 2 :(得分:-1)
我认为你正在寻找这样的东西:
#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后列不排列)。如果你的每个角色都能正确显示,你就不应该看到任何中断。
答案 3 :(得分:-1)
如前面评论中所述,您需要在输出值之前询问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;
}