Getting terminal size in c for windows?

Solution 1:

This prints the size of the console, not the buffer:

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

This code works because srWindow "contains the console screen buffer coordinates of the upper-left and lower-right corners of the display window", and the SMALL_RECT structure "specify the rows and columns of screen-buffer character cells" according to MSDN. I subtracted the parallel sides to get the size of the console window. Since I got 1 less than the actual value, I added one.

Solution 2:

(Partial answer)

This code:

CONSOLE_SCREEN_BUFFER_INFO csbi;
int ret;
ret = GetConsoleScreenBufferInfo(GetStdHandle( STD_OUTPUT_HANDLE ),&csbi);
if(ret)
{
    printf("Console Buffer Width: %d\n", csbi.dwSize.X);
    printf("Console Buffer Height: %d\n", csbi.dwSize.Y);
}

Gives the size of the buffer. The only problem is that dwSize.Y is not really the size of the screen (300 here instead of 25 lines). But dwSize.X matches the column's number. Needs only windows.h to work.

Solution 3:

The below two functions will get the window size somewhat more directly.

Note that I found, using gcc, that neither this approach nor GetConsoleScreenBufferInfo works if the program is piped. That is somewhat of a pain as for/f then does not work either. Apparently the screen data is not available in a pipe.

Um, the above remark is of course enormously stupid. ;) It is STDOUT that is not the screen in a pipe! That does mean I prefer using STD_ERROR_HANDLE above STD_OUTPUT_HANDLE. I am far less likely to direct standard error away from the screen than standard output.

typedef struct _CONSOLE_FONT_INFO {
  DWORD nFont;
  COORD dwFontSize;
} CONSOLE_FONT_INFO, *PCONSOLE_FONT_INFO;

BOOL WINAPI GetCurrentConsoleFont(
   HANDLE             hConsoleOutput,
   BOOL               bMaximumWindow,
   PCONSOLE_FONT_INFO lpConsoleCurrentFont
);

/* Get the window width */
int getww_(void)
{
    CONSOLE_FONT_INFO info;
    GetCurrentConsoleFont(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &info);
    return info.dwFontSize.X;
}

/* Get the window height */
int getwh_(void)
{
    CONSOLE_FONT_INFO info;
    GetCurrentConsoleFont(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &info);
    return info.dwFontSize.Y;
}