2014-10-06 2 views
0

Я ищу способ вывода элементов структуры, которые я определил в программе 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 с в векторе, что, когда я печатаю это все таким образом, записи начинают делать новые линии сами по себе, и пачкая форматирование:

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, где он остановился.

Я мог бы грубой силой и жестко запрограммировать это, да, но мне было интересно, есть ли у кого-нибудь представление о том, как это сделать с помощью cuter?

Спасибо!

ответ

0

Прежде всего, вы можете узнать, насколько широким является терминал, чтобы вы не могли его переполнить. Для этого мы можем использовать ioctl() с TIOCGWINSZ, как показано здесь: https://stackoverflow.com/a/8529354/4323

Тогда мы можем использовать std::ostream::tellp() знать, сколько символов мы писали до сих пор: http://www.cplusplus.com/reference/ostream/ostream/tellp/

Собираем все вместе, мой план будет получить ширину окна, распечатать один столбец, проверить, насколько он широко (или, может быть, вы уже знаете), и дать хорошее представление о том, будет ли следующий столбец слишком широким или нет. Если вы находитесь ближе к концу строки, просто отложите печать этого столбца до тех пор, пока вы не напечатали все строки для столбцов.

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

Я предполагаю, что ваш экран достаточно долго.

  • Во-первых, получите самую длинную длину первого столбца и запомните его. Сделайте то же самое для следующих 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 ("Алиса") = 5.

и третьей колонке один является lengthof ("хорошо") = 4.

Тогда довольно-печать их ...

John______Alice_Time

10.000000_9.98__8.1

good______bad___good

Здесь `_ 'означает пробел.

Смежные вопросы