Getting terminal size in c for windows?

30,619

Solution 1

(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 2

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 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;
}
Share:
30,619

Related videos on Youtube

DrBeco
Author by

DrBeco

Computer Scientist, Cognitive Scientist, Philosophy of Mind, Painter, Poet, Biker and Judoka (that I remember) I just created a nice clone (fork actually) of the Urban Muller language, called BrainForce (now I can keep my job as professor and still uses the language to teach Turing Machines and nice properties). Still don't have a website for it, but I can mail you if you want. All source code available. Translate BF to C. The release is at your disposal here. Lots of options to generate different code for various situations. Blog Beco cc

Updated on May 18, 2020

Comments

  • DrBeco
    DrBeco about 4 years

    How to check ymax and xmax in a console window, under Windows, using plain c?

    There is this piece of code for linux:

    #include <stdio.h>
    #include <sys/ioctl.h>
    int main (void)
    {
        struct winsize max;
        ioctl(0, TIOCGWINSZ , &max);
        printf ("lines %d\n", max.ws_row);
        printf ("columns %d\n", max.ws_col);
    }
    

    Now I wonder how can I do the same for windows. I tried winioctl.h but it does not define struct winsize nor any other with a similar name.

    Any tips? Thanks.

    PS. In linux you also can find the console size using getenv("LINES");. Is there a similar variable under windows?

    PPS. Also, there is always ncurses.h, that I suppose work both systems, but I'm avoiding it because of conflicts with other libraries I have.

    PPPS. This question here Getting terminal width in C? has a lot of tips, so no need to repeat that.

  • DrBeco
    DrBeco over 11 years
    I'm short on time to test it, but it looks like this is the right answer to the question. Would you mind point out the difference between this answer and the one currently accepted that shows the buffer size? Thanks!
  • dgnuff
    dgnuff about 8 years
    @DrBeco In most cases, the buffer size from your answer, and the display window mentioned in this answer have the same width, although this is not required. However, as you note the buffer and windows can and often do have different heights - this is what provides for the ability to scroll back up a Windows console session. I find it easiest to think in terms of a large buffer, with a smaller viewport (display) window that can look at any section of the main buffer.
  • Xam
    Xam about 6 years
    Exactly what I was looking for. +1
  • RhetoricalRuvim
    RhetoricalRuvim almost 5 years
    Or you could use CONSOLE_SCREEN_BUFFER_INFO.dwSize.X and .Y for short.
  • quantum
    quantum over 4 years
    @RhetoricalRuvim CONSOLE_SCREEN_BUFFER_INFO.dwSize is the size of the buffer, which includes scrollback, not the size of the window.
  • Exectron
    Exectron over 3 years
    If STDOUT is redirected to a file, then the GetConsoleScreenBufferInfo() call returns FALSE, so that should be tested.
  • cniggeler
    cniggeler about 3 years
    Since this is a snippet, I add #include <windows.h> and a main() to print getww() and getwh(). When I run that, I get the size of the FONT being used - 12x7 - NOT the console size. Am I doing something wrong?
  • cniggeler
    cniggeler about 3 years
    +1 for suggesting STD_ERROR_HANDLE to get @quantum's code to work if you use it in a script or otherwise need to pipe the output.