Questo esempio è un po' lungo, ma credo che sia il modo più portatile per rilevare le dimensioni terminali. Questo gestisce anche gli eventi di ridimensionamento.
Come suggeriscono tim e rlbond, sto usando ncurses. Garantisce un notevole miglioramento della compatibilità del terminale rispetto alla lettura diretta delle variabili d'ambiente.
#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);
}
Hai considerato l'utilizzo di getenv() ? Ti permette di ottenere le variabili d'ambiente del sistema che contengono le colonne e le righe dei terminali.
In alternativa, usando il tuo metodo, se vuoi vedere cosa vede il kernel come dimensione del terminale (meglio nel caso in cui il terminale venga ridimensionato), dovresti usare TIOCGWINSZ, invece di TIOCGSIZE, in questo modo:
struct winsize w;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
e il codice completo:
#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
}