如何使用iomanip中的setw、setfill和left/right? setfill无法停止输出

15

我想让我的输出看起来像这样:

size       time1       time2
-------------------------------
10         4           8
100        48          16
1000       2937        922
10000      123011      3902
100000     22407380    830722

我知道我需要使用 setw(), setfill(), 和 left。然而,我的尝试一直给我错误的输出。以下是我的一个代码示例:

std::cout << "size" << std::setw(20) << "time" << std::setw(20) << "time2\n";
std::cout << std::setfill('-') << std::setw(60) << "-" << std::endl;
run = 10;
for(int i = 0; i < 5; i++) {
    std::cout << run;
    run *= 10;
    std::cout << std::setw(20) << std::left << time1[i];
    std::cout << std::setw(20) << std::left << time2[i] << "\n";
}

这里是输出结果:

size    time1    time2
------------------------------------------------------------
103-------------------13------------------
100171-----------------199-----------------
100013183---------------667-----------------
10000670130--------------8205----------------
10000014030798-------------1403079888---------

我尝试改变使用 setw() setfill() left 的顺序,但现在我只是盲目尝试。我也搜索了教程。就我所知,我遵循了说明,但仍然无法实现。

如何防止 setfill() 溢出?如何左对齐但使用 setw() 防止数字彼此重叠?

3个回答

8
如何考虑以下方案:
std::cout << "size" << std::setw(20) << "time" << std::setw(20) << "time2\n";
std::cout << std::setfill('-') << std::setw(60) << "-" << std::endl;
run = 10;
std::cout << std::setfill(' ');  //fill with spaces
for(int i = 0; i < 5; i++) {
    std::cout << std::setw(20) << std::left << run;  // fill the run column
    run *= 10;
    std::cout << std::setw(20) << std::left << time1[i];
    std::cout << std::setw(20) << std::left << time2[i] << "\n";
}

1
在 C++20 中,您将能够使用 std::format 来实现此功能:
  std::cout << std::format("{:20}{:20}{:20}\n", "size", "time", "time2");
  std::cout << std::format("{:-<60}\n", "");
  int run = 10;
  for(int i = 0; i < 5; i++) {
    std::cout << std::format("{:<20}{:<20}{:<20}\n", run, time[i], time2[i]);
    run *= 10;
  } 

输出:

size                time                time2               
------------------------------------------------------------
10                  4                   8                   
100                 48                  16                  
1000                2937                922                 
10000               123011              3902                
100000              22407380            830722              

与此同时,您可以使用基于其构建的{fmt}库std::format。{fmt}还提供了print函数,使这一过程更加简单和高效(godbolt):
  fmt::print("{:20}{:20}{:20}\n", "size", "time", "time2");
  fmt::print("{:-<60}\n", "");
  int run = 10;
  for(int i = 0; i < 5; i++) {
    fmt::print("{:<20}{:<20}{:<20}\n", run, time[i], time2[i]);
    run *= 10;
  }

声明: 我是 {fmt} 和 C++20 std::format 的作者。


1

sj0h的回答很好,除了标题没有完全对齐。为了解决这个问题,我在标题行前加上了“left”和“setw”,并且结尾使用了“endl”而不是“\n”。

  std::cout << std::left << std::setw(20) << "size" << std::setw(20) << "time" << std::setw(20) << "time2" << std::endl;

  std::cout << std::setfill('-') << std::setw(60) << "-" << std::endl;
  run = 10;
  std::cout << std::setfill(' ');  //fill with spaces
  for(int i = 0; i < 10; i++) {
      std::cout << std::setw(20) << std::left << run;  // fill the run column
      run *= 10;
      std::cout << std::setw(20) << std::left << time1[i];
      std::cout << std::setw(20) << std::left << time2[i] << std::endl;
  }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接