【问题标题】:Aligning output to the terminal using C++使用 C++ 将输出对齐到终端
【发布时间】:2011-11-20 16:54:28
【问题描述】:

我在将输出与终端对齐时遇到了很多麻烦。我想将向量即vector< vector<double> > myvec; 打印到 myvec[i] 占据终端上第 i 行的输出。组成myvec 的向量大小为 3

这是我尝试打印的方式。

for(unsigned int i=0; i<myvec.size() ; ++i   )
{


cout<<myvec[i][0]<<"     "
    <<myvec[i][1]<<"     "
    <<myvec[i][2]<<'\n';
}

当我打印这个输出时,只有 myvec[i][0] 列的数字正确对齐。其余的数字看起来很乱。有没有一个好方法来对齐这个输出? (忽略图像第5行右侧打印的0.7)

【问题讨论】:

  • 在列之间使用制表符 (\t) 而不是空格 " "。
  • 我们真的需要物理截图吗??

标签: c++ terminal


【解决方案1】:

您可以使用setw() 设置要写入的最小字符数,使用left 将数据输出到左侧。像这样:

cout << setw(8) << left << myvec[i][0];

这应该用空格填充空白,但如果没有,那么你可以这样做:

cout << setw(8) << left << setfill(' ') << myvec[i][0];

为此,您需要#include &lt;iomanip&gt;

【讨论】:

  • 非常感谢!这对我很有效。一个问题是 setw() 的工作。假设 myvec[i][0] 的值为 2.71828,而我这样做 cout &lt;&lt; setw(3) &lt;&lt; left &lt;&lt; myvec[i][0]; 是否意味着只有 2.7 会被打印到输出中?
  • @GaurishTelang No. setw() 设置要写入的最少个字符。
  • 有什么命令可以设置要写入的最大字符数吗?
  • 另外,你必须每次都插入setw(),因为它不是持久的。 (setprecision() 是您问题的答案。)
  • @GaurishTelang 正如 Kerrek 所说。
【解决方案2】:

关于您的代码的几点说明:

对齐类型

quasiverse 的答案为您提供左对齐,即每个数字都从第一个字符位置开始。删除left 使其右对齐,即每个数字都从最后一个字符位置开始。

对齐小数点有点困难。如果要设置小数点后的固定位数,请将left 替换为fixed 并添加setprecision(),为其指定小数点后的位数。例如,显示小数点后两位数:

cout << setw(8) << fixed << setprecision(2) << myvec[i][0];

二维向量

您声明了vector&lt; vector&lt;double&gt; &gt; myvec;,但次要(第二)维度似乎硬编码为 3。这意味着您正在创建一个向量向量,其中每一行都是一个完整的向量对象,存储三个双精度值。

vectors 不在内部存储他们的数据;实际的向量对象只存储元素的数量、指向实际数据存储的指针,也许还有其他一些东西。实际数据存储在单独的块中。这会产生大量开销和内存碎片(每行分配一个块来存储数据)。

例如,对于一个 1000x3 的向量,栈上有一个顶层向量对象,堆上有一个由 1000 个向量对象(每行一个)组成的数组,每个向量对象都指向一个由三个双精度组成的块,所以堆上有 1001 个对象,每次访问都必须通过两个指针。缓慢而低效。

vector 如果长度是固定的,那就大材小用了。所以我建议有一个结构向量,每个结构都有三个双精度:

struct point {
    double x, y, z;
};
vector<point> myvec;

这会将所有数据存储在一个块中,因为point 是完全独立的。那么你的代码是:

for(unsigned int i = 0; i < myvec.size() ; ++i)
{
    cout << setw(8) << left << myvec[i].x << ' ' << setw(8) << left << myvec[i].y 
        << ' ' << setw(8) << left << myvec[i].z << endl;
}

或者,C++ 迭代器的方法:

for(vector<point>::const_iterator elem = myvec.begin(); elem != myvec.end() ; ++elem)
{
    cout << setw(8) << left << elem.x << ' ' << setw(8) << left << elem.y 
        << ' ' << setw(8) << left << elem.z << endl;
}

这节省了对operator[] 的大量调用。如果您的编译器支持新的 C++11 标准,您可以将 for() 行更改为:

for(auto elem = myvec.begin(); elem != myvec.end() ; ++elem)

其中auto 告诉编译器使elemmyvec.begin() 返回的类型相同。另一种不太可能受支持的 C++11 方式是 range-based for loop

for(auto elem: myvec)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-17
    • 2017-12-01
    • 1970-01-01
    • 2020-07-16
    相关资源
    最近更新 更多