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

时间:2014-10-06 07:01:29

标签: c++ formatting containers

我正在寻找一种输出我在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_cell s,当我以这种方式打印它时,条目开始自己创建新行,并弄清楚格式:

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

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

我可以蛮力和硬编码,是的,但是我想知道是否有人知道如何以可行的方式做到这一点?

谢谢!

3 个答案:

答案 0 :(得分:0)

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

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

总而言之,我的计划是获得窗口宽度,打印一列,检查它的宽度(或者您可能已经知道),并且好好猜测下一列是否太宽或不。如果您接近该行的末尾,只需推迟打印该列,直到您打印到目前为止列的所有行为止。

答案 1 :(得分:0)

这里有一些尝试:

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

答案 2 :(得分:0)

我认为你的屏幕足够长。

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

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

例如,

  

John Alice Tim

     

10.000000 9.98 8.1

     好的坏事

第一列的最长长度是你应该记忆的lengthof(“10.000000”)= 9。

第二列一是lengthof(“Alice”)= 5.

,第三列是lengthof(“good”)= 4。

然后漂亮地印刷它们......

  

约翰______ Alice_Time

     

10.000000_9.98__8.1

     

好坏______ ___良好

这里`_'表示空白。