#c #windows-console
#c #windows-консоль
Вопрос:
Я просто возился с CPP и консолью Windows. Мне нужно изменить определенную часть экранного буфера, который у меня есть, но он всегда печатает нужную мне строку плюс пустое квадратное поле.
Есть ли способ удалить это пустое поле?
int screen_w = 120;
int screen_h = 30;
void init_screen(wchar_t* screen_buffer, int screen_w, int screen_h) {
for (int i = 0; i < screen_h; i) {
for (int j = 0; j < screen_w; j) {
if (i != 0 amp;amp; i != 2 amp;amp; i != screen_h - 1 amp;amp;
j != 0 amp;amp; j != screen_w - 1) {
screen_buffer[i * screen_w j] = ' ';
} else {
screen_buffer[i * screen_w j] = '#';
}
}
}
}
int main() {
int screen_s = screen_w * screen_h;
wchar_t *screen_buffer = 0;
screen_buffer = (wchar_t *) calloc(screen_s, sizeof *screen_buffer);
HANDLE c_handle = CreateConsoleScreenBuffer(
GENERIC_WRITE | GENERIC_READ,
0,
0,
CONSOLE_TEXTMODE_BUFFER,
0);
SetConsoleActiveScreenBuffer(c_handle);
DWORD bytes_written = 0;
init_screen(screen_buffer, screen_w, screen_h);
while (1) {
Sleep(1000 / 10);
WriteConsoleOutputCharacterW(c_handle, screen_buffer, screen_s, { 0, 0 }, amp;bytes_written);
wsprintfW(amp;screen_buffer[15 * screen_w 60], L"hello world"); // THIS IS WHAT I DO.
// TRIED OTHER SIMILAR FUNCTIONS.
if (GetAsyncKeyState(VK_SPACE) amp; 0x8000) break;
}
free(screen_buffer = 0);
return 0;
}
И что это показывает:
########################################################################################################################
# #
########################################################################################################################
# #
# #
# #
# #
# #
# #
# #
# #
# #
# #
# #
# #
# hello world▯ #
# #
# #
# #
# #
# #
# #
# #
# #
# #
# #
# #
# #
# #
########################################################################################################################```
Комментарии:
1. Добавил это туда, извините!
2. Может быть, это консольная кодировка? Я понятия не имею…
3.
wsprintfW
копирует весь строковый литерал в экранный буфер, включая завершающий символ NUL. Вероятно, вам нужноwmemcpy
или что-то подобное — что-то, что не работает со строками с нулевым завершением.4. Также обратите внимание, что в документации для wsprintfW говорится: Примечание Не используйте ….
5. Адриан Моул Я на самом деле использовал swprintf раньше. Также пробовал swprintf_s. Всегда один и тот же результат.
Ответ №1:
Проблема в том, что ваш wsprintfW()
вызов (или любая из sprintf
функций семейства) добавит (обязательный) nul
символ-терминатор в сегмент выходного буфера… и это может отображаться как «странный» символ в консолях некоторых платформ.
Итак, вместо того, чтобы пытаться записать форматированную строку в буфер, вместо этого просто используйте процедуру прямого копирования в память.
Следующая строка — вместо вашего wsprintf(...)
вызова — сделает свое дело:
memcpy(amp;screen_buffer[15 * screen_w 60], L"hello world", wcslen(L"hello world") * sizeof(wchar_t));
но вы могли бы сделать код более красивым / простым, используя объявленную (локальную) переменную:
const wchar_t* text = L"hello world";
memcpy(amp;screen_buffer[15 * screen_w 60], text, wcslen(text) * sizeof(wchar_t));
Комментарии:
1. Да, спасибо. Это решило проблему. Но странно, что этот символ не отображается на компьютере моего друга, и он отображается на обоих моих… Ну, я думаю, это решение
2. @void-main-void Существует так много разных мест и способов, с помощью которых вы можете настроить, как консоль Windows отображает символы, отличные от ASCII. Я думаю, что вероятность того, что два разных КОМПЬЮТЕРА будут иметь одинаковую конфигурацию, крайне мала.