格式化:如何水平打印容器

Formatting: how to print containers horizontally?

本文关键字:打印 水平 何水平 格式化      更新时间:2023-10-16

我正在寻找一种方法来输出我在Yahtzee程序中定义的结构元素。

我的结构是:

struct card_cell
{
    std::string name;
    int points;
    int state;
}

我想把它打印成格式

    name1    name2    name3...
    points1  points2  points3...
    state1   state2   state3...

像这样穿过屏幕。

不同类型的结构存储在std::vector<card_cell>中,所以我可以通过迭代向量的成员并依次输出名称、点和状态来实现这一点。

然而,我在向量中有足够的card_cells,当我以这种方式打印它时,条目开始自己制作新行,并破坏格式:

    name1    name2    name3...
    nameN...
    points1  points2  points3...
    pointsN...
    state1   state2   state3...
    stateN...

我希望能够声明类似const int CELLS_PER_LINE = 6;的东西,当我的迭代打印出该数量的name时,它将停止,开始一行新行,并打印接下来的6个points值。当它最终到达state s的末尾时,它将形成一条新行,并开始打印它停止的下一组name s。

我可以用暴力和硬编码,是的,但我想知道是否有人知道如何用一种更可爱的方式来做这件事?

谢谢!

首先你可能想知道终端有多宽,这样你就可以确保不会溢出它。为此,我们可以将ioctl()TIOCGWINSZ一起使用,如下所示:https://stackoverflow.com/a/8529354/4323

然后,我们可以使用std::ostream::tellp()来了解到目前为止我们已经写了多少个字符:http://www.cplusplus.com/reference/ostream/ostream/tellp/

综合来看,我的计划是获得窗口宽度,打印一列,检查它的宽度(或者你可能已经知道了),并很好地猜测下一列是否太宽。如果您接近行的末尾,只需将该列的打印推迟到打印完该列的所有行之后。

这里有一些尝试:

void printCells(std::vector<card_cell> const& cells)
{
   // Compute the number of screens you would need to write
   // the cells.
   int numScreens = (cells.size()+CELLS_PER_LINE-1)/CELLS_PER_LINE;
   // Iterators to iterate over all the cells.
   std::vector<card_cell>::const_iterator iter = cells.begin();
   std::vector<card_cell>::const_iterator end = cells.end();
   // Loop over the number of screens needed.
   for ( int i = 0; i != numScreens; ++i )
   {
      // While printing the cells in a screen we have to make sure that:
      // 1. We don't print more than CELLS_PER_LINE.
      // 2. We stop when we are at the end of the cells.
      int count = 0;
      std::vector<card_cell>::const_iterator iter2 = iter;
      // Iterate over the cells for the names and print the names.
      for ( ;
            iter2 != end && count != CELLS_PER_LINE;
            ++iter2, ++count )
      {
         // Figure out how much width to use for each name.
         // Hard coded to 10 here.
         std::cout << std::setw(10) << iter2->name;
      }
      std::cout << std::endl; 
      // Iterate over the cells for the points and print the points.
      for ( count = 0, iter2 = iter;
            iter2 != end && count != CELLS_PER_LINE;
            ++iter2, ++count )
      {
         // Figure out how much width to use for each point.
         // Hard coded to 10 here.
         std::cout << std::setw(10) << iter2->points;
      }
      std::cout << std::endl; 
      // Iterate over the cells for the states and print the states.
      for ( count = 0, iter2 = iter;
            iter2 != end && count != CELLS_PER_LINE;
            ++iter2, ++count )
      {
         // Figure out how much width to use for each state.
         // Hard coded to 10 here.
         std::cout << std::setw(10) << iter2->state;
      }
      std::cout << std::endl; 
      std::cout << std::endl; 
      iter = iter2;
   }
}

我认为您的屏幕足够长。

  • 首先,获取第一列的最长长度并记住它。对接下来的CELLS_PER_LINE - 1元素也这样做
  • 其次,打印第一个CELLS_PER_LINE元素的name。如果某个项目的长度小于您记忆的longest length,请填空。然后按照上述规则打印pointsstate

现在您已经漂亮地打印了第一个CELLS_PER_LINE元素。输出一个换行符并执行相同操作。

例如

John Alice Tim

10.000000 9.98 8.1

好的坏的好的

第一列的最长长度是您应该记住的长度("104000000")=9。

第二列1的长度为("Alice")=5。

第三列1的长度为("良好")=4。

然后漂亮地打印它们。。。

John ______ Alice_Time

104000000_9.98__8.1

好______坏__好

这里"_"的意思是空白。