Получить размер окна терминала (строки/столбцы)

Есть ли какой-либо надежный способ получения количества столбцов/строк текущего окна выходных терминалов?

Я хочу получить эти числа в программе на C/С++.

Я ищу в основном решение GNU/Linux, но также нуждаюсь в решении Windows.

Ответ 1

Для Unix (-based) используйте ioctl(2) и TIOCGWINSZ:


#include <sys/ioctl.h> //ioctl() and TIOCGWINSZ

// ...

struct winsize size;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &size);

/* size.ws_row is the number of rows, size.ws_col is the number of columns. */

// ...

Кроме того, хотя я не прикасался к Windows последние пять лет, GetConsoleScreenBufferInfo() должен помочь вам получить размер окна консоли.

Ответ 2

В Windows используйте следующий код для печати размера окна консоли (заимствованного из здесь):

#include <windows.h>

int main(int argc, char *argv[]) 
{
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    int columns, rows;

    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
    columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
    rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;

    printf("columns: %d\n", columns);
    printf("rows: %d\n", rows);
    return 0;
}

В Linux используйте вместо этого (заимствованный из здесь):

#include <sys/ioctl.h>
#include <stdio.h>
#include <unistd.h>

int main (int argc, char **argv)
{
    struct winsize w;
    ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);

    printf ("lines %d\n", w.ws_row);
    printf ("columns %d\n", w.ws_col);
    return 0;  // make sure your main returns int
}

Ответ 3

Чтобы расширить ответ @herohuyongtao для Windows. Свойство .srWindow дает ответ на размер окна консоли, то есть видимые строки и столбцы. Это не говорит, какова фактическая ширина и высота ширины буфера экрана, которая может быть больше, если в окне есть полосы прокрутки. Если это так, используйте .dwSize:

CONSOLE_SCREEN_BUFFER_INFO sbInfo;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &sbInfo);
int availableColumns = sbInfo.dwSize.X;
int availableRows = sbInfo.dwSize.Y;

Ответ 4

В GNU/Linux с использованием libtermcap (https://www.gnu.org/software/termutils/manual/termcap-1.3/html_mono/termcap.html) создайте demo.c:

#include <stdio.h>
#include <stdlib.h>
#include <curses.h>
#include <term.h>

static char term_buffer[2048];

void
init_terminal_data (void)
{

  char *termtype = getenv ("TERM");
  int success;

  if (termtype == NULL)
    fprintf (stderr, "Specify a terminal type with `setenv TERM <yourtype>'.\n");

  success = tgetent (term_buffer, termtype);
  if (success < 0)
    fprintf (stderr, "Could not access the termcap data base.\n");
  if (success == 0)
    fprintf (stderr, "Terminal type `%s' is not defined.\n", termtype);
}

int
main ()
{
  init_terminal_data ();
  printf ("Got: Lines: %d, Columns: %d\n", tgetnum ("li"), tgetnum ("co"));
  return 0;
}

Затем скомпилируйте с помощью gcc -o demo.x demo.c -ltermcap и запустите, чтобы дать:

$ ./demo.x
Got: Lines: 24, Columns: 80

Я сомневаюсь, что это сильно помогает Windows, но я не знаю этой платформы.

(Некоторые из этого кода копируются прямо из документации termcap.)