Getting terminal width in C?

This example is a bit on the lengthy side, but I believe it's the most portable way of detecting the terminal dimensions. This also handles resize events.

As tim and rlbond suggests, I'm using ncurses. It guarantees a great improvement in terminal compatability as compared to reading environment variables directly.

#include <ncurses.h>
#include <string.h>
#include <signal.h>

// SIGWINCH is called when the window is resized.
void handle_winch(int sig){
  signal(SIGWINCH, SIG_IGN);

  // Reinitialize the window to update data structures.
  endwin();
  initscr();
  refresh();
  clear();

  char tmp[128];
  sprintf(tmp, "%dx%d", COLS, LINES);

  // Approximate the center
  int x = COLS / 2 - strlen(tmp) / 2;
  int y = LINES / 2 - 1;

  mvaddstr(y, x, tmp);
  refresh();

  signal(SIGWINCH, handle_winch);
}

int main(int argc, char *argv[]){
  initscr();
  // COLS/LINES are now set

  signal(SIGWINCH, handle_winch);

  while(getch() != 27){
    /* Nada */
  }

  endwin();

  return(0);
}

Have you considered using getenv() ? It allows you to get the system's environment variables which contain the terminals columns and lines.

Alternatively using your method, if you want to see what the kernel sees as the terminal size (better in case terminal is resized), you would need to use TIOCGWINSZ, as opposed to your TIOCGSIZE, like so:

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

and the full code:

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