Question

Je cherchais un moyen d’obtenir la largeur du terminal à partir de mon programme C. Ce que je n'arrête pas de dire, c'est quelque chose comme:

#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, je reçois

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 une meilleure? Si non, comment puis-je le faire fonctionner?

EDIT: le code fixe 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;
}
Était-ce utile?

La solution

Avez-vous envisagé d'utiliser getenv () ? Il vous permet d’obtenir les variables d’environnement du système contenant les colonnes et les lignes du terminal.

Vous pouvez également utiliser votre méthode pour voir ce que le noyau considère comme la taille du terminal (mieux si le terminal est redimensionné), vous devrez utiliser TIOCGWINSZ, par opposition à votre TIOCGSIZE, comme suit:

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
}

Autres conseils

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

Comme le suggèrent tim et rlbond, j’utilise ncurses. Il garantit une grande amélioration de la compatibilité des terminaux par rapport à la lecture directe de 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);
}
#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 termcap en utilisant info termcap pour plus de détails.

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

En supposant que vous soyez sur Linux, je pense que vous souhaitez utiliser la bibliothèque ncurses . au lieu. Je suis à peu près sûr que les choses que vous avez faites ne sont pas dans stdlib.

Donc, ne suggérez pas de réponse ici, mais:

linux-pc: ~ / scratch $ echo $ LINES

49

linux-pc: ~ / scratch $ printenv | GREP LINES

linux-pc: ~ / scratch $

Ok, et je remarque que si je redimensionne le terminal GNOME, les variables LINES et COLUMNS suivent cela.

Un peu comme si le terminal GNOME créait ces variables d’environnement lui-même?

Voici les appels de fonction pour la variable d'environnement déjà suggérée:

int lines = atoi(getenv("LINES"));
int columns = atoi(getenv("COLUMNS"));
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top