【问题标题】:Formatting: how to print containers horizontally?格式化:如何水平打印容器?
【发布时间】:2014-10-06 07:01:28
【问题描述】:

我正在寻找一种方法来输出我在尝试制作的 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 值。当它最终到达states 的末尾时,它将形成一个新行并开始打印下一组names。

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

谢谢!

【问题讨论】:

    标签: c++ formatting containers


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

      这里有一些尝试:

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

      【讨论】:

        【解决方案3】:

        我假设你的屏幕足够长。

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

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

        例如,

        约翰·爱丽丝·蒂姆

        10.000000 9.98 8.1

        好的不好的

        第一列的最长长度是lengthof("10.000000") = 9,你应该记住。

        第二列是lengthof("Alice") = 5。

        第三列是lengthof("good") = 4。

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

        约翰_爱丽丝_时间

        10.000000_9.98__8.1

        好______坏___好

        这里的“_”表示空白。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-12-18
          • 2015-04-09
          • 2018-02-01
          相关资源
          最近更新 更多