Пожалуйста, предложите что-нибудь лучше, чем функция gotoxy в C++

Я написал программу, состоящую из множества и множества функций, каждая из которых выводит несколько вещей на консоль, когда им передается управление. Теперь я пытаюсь напечатать все в центре экрана, а не в верхнем левом углу экрана. Единственное, что я знаю для этой цели, — это функция gotoxy в Windows.h. Теперь это была бы чрезвычайно лихорадочная работа, потому что мне пришлось бы размещать gotoxy над каждым "cout". Есть ли способ установить курсор в определенную позицию на экране, и каждый раз, когда что-либо печатается, печать начинается с этой конкретной позиции.


person Rafay    schedule 25.05.2011    source источник


Ответы (4)


Напишите небольшую вспомогательную функцию (например, printCentered(std::string) ), которая получает строку для печати. Эта функция перемещает курсор в центр, а затем печатает параметр. Затем замените свои couts вызовом этой функции.

person Hyperboreus    schedule 25.05.2011
comment
Возможно, std::string был бы лучшим выбором (или, по крайней мере, const char *). - person Etienne de Martel; 25.05.2011
comment
Для реализации этой вещи я должен изменить всю свою программу, чего я пытаюсь избежать. Есть ли альтернатива, которую вы можете предложить? - person Rafay; 25.05.2011
comment
Я предполагаю, что один вызов awk или sed должен сделать все редактирование вашего существующего кода. Другим способом было бы перехватывать вызовы ‹‹ через cout, но кто-то еще должен был бы сказать вам, (а) это возможно и (б) как это сделать. - person Hyperboreus; 25.05.2011
comment
@Hyperboreus: переназначение cout (или любого стандартного потока) определенно возможно, например, у меня есть код, превращающий каждую строку, написанную в cerr, в окно сообщения. Но это много дополнительной работы. Стоит ли это того, зависит от того, сколько строк кода необходимо обновить, чтобы вместо этого вызвать центрированную функцию. - person Ben Voigt; 25.05.2011
comment
@Бен Спасибо. Также я предполагаю, что этот способ требует гораздо больше работы, чем передача каждого исходного кода C через awk или sed. - person Hyperboreus; 25.05.2011
comment
@Hyperboreus: это много работы. Является ли это дополнительной работой, спорный вопрос, поскольку ваше исправление исправит только вывод простых строк. Не существует регулярного выражения, которое превращало бы cout << "A = " << hex << 5 << endl; в вызов printCentered(string). - person Ben Voigt; 25.05.2011
comment
Затем используйте sed для ввода gotoxy(100,100); перед каждым кут. - person Hyperboreus; 25.05.2011
comment
@Hyperboreus: предположительно правильные координаты зависят от строки, то есть left = (screen_width - line_length)/2;. - person Ben Voigt; 26.05.2011

  1. Не используйте cout или любой другой потоковый ввод-вывод для рисования по всему экрану. Нет смысла «позиционировать» поток, если он перенаправляется на другое устройство.
  2. Вызывать функции консоли Win32 напрямую, например этот пример, который рисует строку состояния в консольной программе.
person Aaron Klotz    schedule 25.05.2011

Следующее позволяет легко найти и заменить и позаботится о установке курсора в центр:

#include <iostream>

std::ostream& PrintCentered(){
  // comment in the following if you're experiencing
  // weird output due to io-buffering like @Ben says in a comment
  //std::cout.flush();
  gotoxy(your_x, your_y);
  return std::cout;
}

Теперь просто найдите и замените свои вызовы std::cout указанной выше функцией там, где вы хотите, чтобы она была сосредоточена. Использование после замены должно выглядеть так:

PrintCentered() << "your message";
person Xeo    schedule 25.05.2011
comment
+1: вот почему я боюсь и в то же время восхищаюсь c++ :P - person BlackBear; 25.05.2011
comment
Необходима некоторая синхронизация, так как cout можно буферизовать. - person Ben Voigt; 25.05.2011
comment
cout << "xyz"; PrintCentered() << "your message"; может привести к gotoxy, за которым следует вывод xyzyourmessage, если xyz был помещен в буфер, а не распечатан немедленно. Если вы хотите упорядочить вывод с помощью вызовов других функций, вам нужно очистить буферы. - person Ben Voigt; 25.05.2011
comment
@Ben: О, да, но эта проблема существует, если ОП просто вставляет вызовы gotoxy в свой код. Можно добавить вызов cout.flush() перед gotoxy. - person Xeo; 25.05.2011

Предполагая, что вы используете cout для записи, этот хак должен выполнить эту работу:

 #define AT_CENTER( stuff ) goto( 100, 100 ); cout << stuff;

Где 100, 100 следует заменить вашими конкретными значениями. Затем в использовании:

 AT_CENTER( "The meaning of life is " << x );
person Community    schedule 25.05.2011
comment
@Etienne: будучи сам атеистом, я все же хотел бы процитировать одну священную книгу: Кто без греха, пусть первый бросит камень ;) - person 0xC0000022L; 25.05.2011
comment
Ну а для малых значений просто ужас. Вы должны быть чувствительной душой - там гораздо хуже. А я говорил, что это взлом. И на самом деле я использую что-то очень похожее во всех своих сообщениях об ошибках. - person ; 25.05.2011