使用 C++ 将输出对齐到终端

发布于 2024-12-05 13:27:48 字数 519 浏览 0 评论 0原文

我在将输出与终端对齐时遇到很多麻烦。我想打印向量的向量,即 vector<;矢量<双> > 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)

在此处输入图像描述

I am having a lot of trouble aligning my output to the terminal. I want to print a vector of vectors viz vector< vector<double> > myvec; to the output where myvec[i] occupies the ith row on the terminal. The vectors composing myvec have size 3

This is the way I am trying to print it.

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


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

When I print this to output only the myvec[i][0] column of numbers is aligned properly. The rest of the numbers look messy. Is there a good way to align this output?
(Ignore the 0.7 printed to the right on line 5 of image)

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

丶视觉 2024-12-12 13:27:48

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

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

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

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

为此,您将需要 #include

You can use setw() to set the minimum number of characters you want to be written and left to output the data to the left. Like this:

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

This should fill the empty space with spaces but if not, then you can do:

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

You will need to #include <iomanip> for this.

℡寂寞咖啡 2024-12-12 13:27:48

关于您的代码只有几个注释:

对齐类型

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

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

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

2-D Vectors

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

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

例如,对于 1000x3 向量,堆栈上有顶级向量对象,堆上有 1000 个向量对象(每行一个)的数组,每个向量对象都指向一个由三个双精度数组成的块,因此您有堆上有1001个对象,每次访问都要经过两个指针。缓慢且低效。

如果长度是固定的,向量就太过分了。因此,我建议使用一个结构向量,每个结构具有三个双精度数:

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 方式是 基于范围的 for 循环

for(auto elem: myvec)

Just a couple notes about your code:

Alignment types

quasiverse's answer gives you left justification, i.e. every number starts in the first character position. Drop the left to make it right-justify, i.e. every number starts in the last character position.

Aligning the decimal points is a bit harder. If you want to set a fixed number of digits past the decimal point, then replace the left with fixed and add setprecision(), giving it the number of digits you want past the decimal. For example, to show two digits past the decimal:

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

2-D Vectors

You're declaring vector< vector<double> > myvec;, but the minor (second) dimension appears hardcoded to 3. This means that you are creating a vector of vectors, where each row is an entire vector object with storage for three doubles.

vectors don't store their data internally; the actual vector object just stores the number of elements, a pointer to the actual data storage, and maybe a couple other things. The actual data is stored in a separate block. This will create a lot of overhead and memory fragmentation (every row allocates a block to store the data).

For example, for a 1000x3 vector, there is the top-level vector object on the stack, an array of 1000 vector objects (one per row) on the heap, and each of those points to a block of three doubles, so you have 1001 objects on the heap and every access has to go through two pointers. Slow and inefficient.

vector is overkill if the length is fixed. So I'd recommend having a vector of structures, with each structure having three doubles:

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

This stores all the data in one block, since point is completely self-contained. Then your code is:

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;
}

Or, the C++ iterator way to do it:

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;
}

This saves a bunch of calls to operator[]. If your compiler supports the new C++11 standard, you can change the for() line to:

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

where auto tells the compiler to make elem the same type as what myvec.begin() returns. Another C++11 way, less likely to be supported, is the range-based for loop:

for(auto elem: myvec)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文