使用 C++ 将输出对齐到终端
我在将输出与终端对齐时遇到很多麻烦。我想打印向量的向量,即 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)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用
setw()
设置要写入的最小字符数,使用left
将数据输出到左侧。像这样:这应该用空格填充空白,但如果没有,那么您可以这样做:
为此,您将需要
#include
。You can use
setw()
to set the minimum number of characters you want to be written andleft
to output the data to the left. Like this:This should fill the empty space with spaces but if not, then you can do:
You will need to
#include <iomanip>
for this.关于您的代码只有几个注释:
对齐类型
准宇宙的答案为您提供了左对齐,即每个数字都从第一个字符位置开始。删除
left
使其右对齐,即每个数字都从最后一个字符位置开始。对齐小数点有点困难。如果要设置小数点后的固定位数,请将
left
替换为fixed
并添加set precision()
,给出您想要的小数点后的位数。例如,要显示小数点后两位数:2-D Vectors
您要声明
vector<;矢量<双> > myvec;
,但次要(第二)维度似乎硬编码为 3。这意味着您正在创建一个向量的向量,其中每行都是一个完整的向量对象,可存储三个双精度数。向量
不会在内部存储数据;实际的向量对象只存储元素的数量、指向实际数据存储的指针,也许还存储其他一些东西。实际数据存储在单独的块中。这会产生大量的开销和内存碎片(每一行分配一个块来存储数据)。例如,对于 1000x3 向量,堆栈上有顶级向量对象,堆上有 1000 个向量对象(每行一个)的数组,每个向量对象都指向一个由三个双精度数组成的块,因此您有堆上有1001个对象,每次访问都要经过两个指针。缓慢且低效。
如果长度是固定的,
向量
就太过分了。因此,我建议使用一个结构向量,每个结构具有三个双精度数:这将所有数据存储在一个块中,因为
point
是完全独立的。那么你的代码是:或者,C++ 迭代器的方式来做到这一点:
这节省了对
operator[]
的大量调用。如果您的编译器支持新的 C++11 标准,您可以将for()
行更改为:其中
auto
告诉编译器生成elem
与myvec.begin()
返回的类型相同。另一种不太可能被支持的 C++11 方式是 基于范围的 for 循环: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
withfixed
and addsetprecision()
, giving it the number of digits you want past the decimal. For example, to show two digits past the decimal: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.vector
s 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:This stores all the data in one block, since
point
is completely self-contained. Then your code is:Or, the C++ iterator way to do it:
This saves a bunch of calls to
operator[]
. If your compiler supports the new C++11 standard, you can change thefor()
line to:where
auto
tells the compiler to makeelem
the same type as whatmyvec.begin()
returns. Another C++11 way, less likely to be supported, is the range-based for loop: