如何对齐输出?

How to align output?

如何对齐输出?

我试过了

  for(int x = 0; i<5; i++)
  cout<<a[x]<<setw(5)<<"|"<<setw(5)<<b[x]<<endl;

如果所有 a 的字符长度都相同,则输出如下

 frd     |     hehe
 asd   |     hoho
 .....
 .....

但如果长度不同

 frd     |     hehe
 asdfg     |     hohoo

如何解决?

尝试使用 printf。说真的,它有效。

例如:

#include <cstdio>
int main() {
    printf("%-10s | %10s\n", "asd", "asdad");
    printf("%-10s | %10s\n", "asd", "adad");
    printf("%-10s | %10s\n", "adsada", "adad");
    printf("%-10s | %10s\n", "addasda", "adad");
    printf("%-10s | %10s\n", "asdsd", "dad");
    printf("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", "asdsd", "dad");
    printf("%-10s | %-10s\n", "asd", "asdad");
    printf("%-10s | %-10s\n", "asd", "adad");
    printf("%-10s | %-10s\n", "adsada", "adad");
    printf("%-10s | %-10s\n", "addasda", "adad");
    printf("%-10s | %-10s\n", "asdsd", "dad");
}

给予

asd        |      asdad
asd        |       adad
adsada     |       adad
addasda    |       adad
asdsd      |        dad
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
asd        | asdad     
asd        | adad      
adsada     | adad      
addasda    | adad      
asdsd      | dad    

您可以将 setw(#) 更改为您需要的任何数字。

#include<iostream>
#include<iomanip>
#include<string>
using namespace std;

int main()
{
    string a[5] = {"afdfadsf","ggrggeee","fdsafsda","erererefdsfd","sdfdsfdffdf"};
    string b[5] = {"fdsfdsfd", "fdsfdsaffdf","fdsfsadfdfd","rererrefdfd","zzzzzzzfdfd"};
    for(int i = 0; i<5; i++)
        cout << left << setw(15) << a[i] << left << setw(15) << b[i] <<  endl;
}

在您建议的代码中:

    cout<<a[x]<<setw(5)<<"|"<<setw(5)<<b[x]<<endl;

您有两个导致错位的问题。 (1) a[x] 没有设置宽度,所以不做任何调整直接输出;和 (2) 根据您寻求的对齐方式,为 std::cout 指定宽度时的默认对齐方式将 right 对齐。

(另外,如我的评论所述,在您的第一个示例中,a[0]a[1] 的长度不能与示例建议的长度相同。"frd " 存储有额外的whitespace(或 "asd\b" 与嵌入的 backspace 一起存储)否则 "a[x]|" 的输出将对齐。)

要为 ab 的输出提供对齐方式,您必须至少指定 a[x]std::setw(n) 的宽度。此外,除非您希望 a[x]std::setw(5) 创建的字段右侧对齐,否则您必须通过设置 std::ios_base::fmtflags with std::setiosflags(std::ios_base::left) (or simply std::left). See std::setiosflags.

来控制对齐方式

当您为流设置格式标志时,您是在 Bitmap 类型中设置位,这些位将在当前对 std::cout 的调用完成后保持设置。因此,要自己整理并将流的标志状态恢复为默认值,您要么 (1) 必须通过使用 std::ios_base::fmtflags 捕获所有标志来为流保存 fmtflags 或 (2) 您必须重置您使用 std::resetiosflags(...).

设置的个人标志

因此,如果我理解您的问题和您的对齐要求(尽管不清楚您希望 b[x] 对齐的方式),您可以将 ab 都左对齐通过:

    std::cout << "left justified output (both a & b)\n\n";
    for (size_t i = 0; i < a.size(); i++)
        std::cout << std::left  << std::setw(5) 
                << a[i] << " | " << b[i] << '\n';

或者您可以将 a 左对齐,然后恢复默认标志状态,让 b 以默认(右)对齐方式输出,例如

    std::cout << "\nleft justified output for a, default for b\n\n";
    for (size_t i = 0; i < a.size(); i++)
        std::cout << std::left  << std::setw(5) 
                << a[i] << " | " << std::resetiosflags(std::ios_base::left) 
                << std::setw(5) << b[i] << '\n';

举个例子,你可以这样做:

#include <iostream>
#include <iomanip>
#include <vector>
#include <string>

int main (void) {

    std::vector<std::string> a = { "frd", "asdfg", "asd", "quack" }, 
                             b = { "hehe", "hohoo", "haloo", "hack" };

    std::cout << "left justified output (both a & b)\n\n";
    for (size_t i = 0; i < a.size(); i++)
        std::cout << std::left  << std::setw(5) 
                << a[i] << " | " << b[i] << '\n';

    std::cout << "\nleft justified output for a, default for b\n\n";
    for (size_t i = 0; i < a.size(); i++)
        std::cout << std::left  << std::setw(5) 
                << a[i] << " | " << std::resetiosflags(std::ios_base::left) 
                << std::setw(5) << b[i] << '\n';
}

例子Use/Output

$ ./bin/setwstring
left justified output (both a & b)

frd   | hehe
asdfg | hohoo
asd   | haloo
quack | hack

left justified output for a, default for b

frd   |  hehe
asdfg | hohoo
asd   | haloo
quack |  hack

注意:如果你想在输出操作过程中对标志进行多次更改,然后将所有格式标志恢复到它们的原始状态,你可以使用:

    std::ios_base::fmtflags f = std::cout.flags (); // save ios_base flags
    // do output, set flags as desired
    std::cout.flags (f);                            // restore saved flags

如果这解决了您试图实现的对齐问题,请告诉我。