Консоль, отображающая конец символа строки

#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. Я думаю, что вероятность того, что два разных КОМПЬЮТЕРА будут иметь одинаковую конфигурацию, крайне мала.