shell 获取终端窗口的大小(行/列)

fnatzsnv  于 2023-03-19  发布在  Shell
关注(0)|答案(6)|浏览(233)

有没有可靠的方法可以获得当前输出终端窗口的列/行数?
我想在C/C++程序中检索这些数字。
我正在寻找一个GNU/Linux的解决方案主要,但也需要一个Windows的解决方案.

xwmevbvl

xwmevbvl1#

在Windows上,使用以下代码打印控制台窗口的大小(借用自quantum的答案here):

#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上,请使用以下代码(借用John T的答案here):

#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
}
xfyts7mz

xfyts7mz2#

对于Unix(基于),请使用ioctl(2)TIOCGWINSZ

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

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()应该可以帮助您获得控制台窗口的大小。

mxg2im7a

mxg2im7a3#

下面是一个在Windows和Linux中都适用的解决方案:

#if defined(_WIN32)
#define WIN32_LEAN_AND_MEAN
#define VC_EXTRALEAN
#include <Windows.h>
#elif defined(__linux__)
#include <sys/ioctl.h>
#endif // Windows/Linux

void get_terminal_size(int& width, int& height) {
#if defined(_WIN32)
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
    width = (int)(csbi.srWindow.Right-csbi.srWindow.Left+1);
    height = (int)(csbi.srWindow.Bottom-csbi.srWindow.Top+1);
#elif defined(__linux__)
    struct winsize w;
    ioctl(fileno(stdout), TIOCGWINSZ, &w);
    width = (int)(w.ws_col);
    height = (int)(w.ws_row);
#endif // Windows/Linux
}

#include <iostream>
using namespace std;
int main() {
    int width=0, height=0;
    get_terminal_size(width, height);
    cout << "width=" << width << ", height=" << height << endl;
    cin.get();
    return 0;
}
iaqfqrcu

iaqfqrcu4#

要在Windows中展开@herohuyongtao,.srWindow属性给出了控制台窗口大小的答案,即可见的行和列。这并没有说明实际可用的屏幕缓冲区宽度和高度,如果窗口包含滚动条,该值可能会更大。如果是这种情况,请使用.dwSize:

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

qxgroojn5#

在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有多大帮助,我不知道那个平台。
(Some直接从termcap文档中复制。)

ldioqlga

ldioqlga6#

历经悲痛:

auto const w(WEXITSTATUS(std::system("exit `tput cols`")));
  auto const h(WEXITSTATUS(std::system("exit `tput lines`")));

相关问题