Как я могу перезаписать одну и ту же часть консоли в консольном приложении С++ для Windows, не используя стороннюю библиотеку?

У меня есть консольное приложение, которое должно отображать состояние элементов, но вместо того, чтобы прокручивать текст, как сумасшедший, я бы предпочел, чтобы текущий статус продолжал отображаться на тех же строках. Для примера:

Running... nn% complete
Buffer size: bbbb bytes

должен быть выход, где "nn" - текущий процент, а "bbbb" - размер буфера, периодически обновляемый в тех же строках консоли.

Первый подход, который я взял, просто напечатал правильное количество обратных пространств на консоли перед печатью нового состояния, но у этого есть неприятное мерцание, от которого я хочу избавиться. Я также хочу придерживаться стандартной библиотеки или функциональности, предоставляемой MS (VC 8), чтобы не вводить другую зависимость для этой простой необходимости.

Ответы

Ответ 1

Вы можете использовать SetConsoleCursorPosition. Вам нужно будет вызвать GetStdHandle, чтобы получить дескриптор выходного буфера.

Ответ 2

Джозеф, JP и кодирование TheWheel предоставили ценную помощь.

В моем простом случае наиболее прямолинейный подход, по-видимому, основывался на КодированииВыхода:

// before entering update loop
HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO bufferInfo;
GetConsoleScreenBufferInfo(h, &bufferInfo);

// update loop
while (updating)
{
  // reset the cursor position to where it was each time
  SetConsoleCursorPosition(h, bufferInfo.dwCursorPosition);

  //...
  // insert combinations of sprintf, printf, etc. here
  //...
}

Для более сложных проблем полный консольный API, предоставленный JP answer, в координации с примерами, представленными через ссылка из ответа Джозефа, может оказаться полезно, но я нашел работу, необходимую для использования CHAR_INFO слишком утомительного для такого простого приложения.

Ответ 3

Если вы печатаете с помощью \r и не используете функцию, которая будет генерировать новую строку или добавить \n до конца, курсор вернется к началу строки и просто распечатает следующую вещь, которую вы положили, Генерация полной строки перед печатью может также уменьшить мерцание.

ОБНОВЛЕНИЕ. Вопрос был изменен на 2 строки вывода вместо 1, что делает мой ответ больше не завершен. Скорее всего, необходим более сложный подход. JP имеет правильную идею с API консоли. Я считаю, что следующий сайт детализирует многие вещи, которые вам понадобятся для достижения вашей цели. На сайте также упоминается, что ключ к уменьшению мерцания - это сделать все вне экрана перед его отображением. Это верно, когда вы показываете что-либо на экране, будь то текст или графика (2D или 3D).

http://www.benryves.com/tutorials/?t=winconsole

Ответ 5

В Linux вы можете выполнить это, напечатав \b и/или\r до stderr. Возможно, вам придется поэкспериментировать, чтобы найти правильную комбинацию вещей в Windows.