113 votes

Obtenir la largeur du terminal en C ?

J'ai cherché un moyen d'obtenir la largeur du terminal à partir de mon programme C. Ce que je trouve toujours, c'est quelque chose du genre :

#include <sys/ioctl.h>
#include <stdio.h>

int main (void)
{
    struct ttysize ts;
    ioctl(0, TIOCGSIZE, &ts);

    printf ("lines %d\n", ts.ts_lines);
    printf ("columns %d\n", ts.ts_cols);
}

Mais à chaque fois que j'essaie, j'obtiens

austin@:~$ gcc test.c -o test
test.c: In function ‘main’:
test.c:6: error: storage size of ‘ts’ isn’t known
test.c:7: error: ‘TIOCGSIZE’ undeclared (first use in this function)
test.c:7: error: (Each undeclared identifier is reported only once
test.c:7: error: for each function it appears in.)

Est-ce la meilleure façon de procéder, ou existe-t-il un meilleur moyen ? Sinon, comment faire pour que cela fonctionne ?

EDIT : le code corrigé est

#include <sys/ioctl.h>
#include <stdio.h>

int main (void)
{
    struct winsize w;
    ioctl(0, TIOCGWINSZ, &w);

    printf ("lines %d\n", w.ws_row);
    printf ("columns %d\n", w.ws_col);
    return 0;
}

151voto

John T Points 14067

Avez-vous envisagé d'utiliser getenv() ? Il vous permet d'obtenir les variables d'environnement du système qui contiennent les colonnes et les lignes des terminaux.

Alternativement, en utilisant votre méthode, si vous voulez voir ce que le noyau voit comme la taille du terminal (c'est mieux au cas où le terminal est redimensionné), vous devriez utiliser TIOCGWINSZ, par opposition à votre TIOCGSIZE, comme ceci :

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

et le code complet :

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

19voto

gamen Points 642

Cet exemple est un peu long, mais je pense que c'est le moyen le plus portable de détecter les dimensions du terminal. Il gère également les événements de redimensionnement.

Comme le suggère Tim et rlbond, j'utilise ncurses. Il garantit une grande amélioration de la compatibilité avec les terminaux par rapport à la lecture directe des variables d'environnement.

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

13voto

Juliano Points 13802
#include <stdio.h>
#include <stdlib.h>
#include <termcap.h>
#include <error.h>

static char termbuf[2048];

int main(void)
{
    char *termtype = getenv("TERM");

    if (tgetent(termbuf, termtype) < 0) {
        error(EXIT_FAILURE, 0, "Could not access the termcap data base.\n");
    }

    int lines = tgetnum("li");
    int columns = tgetnum("co");
    printf("lines = %d; columns = %d.\n", lines, columns);
    return 0;
}

Doit être compilé avec -ltermcap . Il y a beaucoup d'autres informations utiles que vous pouvez obtenir en utilisant termcap. Consultez le manuel de termcap en utilisant info termcap pour plus de détails.

3voto

rlbond Points 24215

Si vous avez installé ncurses et que vous l'utilisez, vous pouvez utiliser getmaxyx() pour trouver les dimensions du terminal.

-1voto

tim Points 504

En supposant que vous êtes sous Linux, je pense que vous voulez utiliser l'option ncurses bibliothèque à la place. Je suis presque sûr que le truc ttysize que vous avez n'est pas dans stdlib.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X