Je cherchais un moyen d'obtenir la largeur du terminal à partir de mon programme C. Ce que je continue de proposer, 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'essaye
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 solution? Sinon, comment puis-je faire en sorte que cela fonctionne?
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;
}
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 (mieux dans le cas où le terminal est redimensionné), vous devrez 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
}
Cet exemple est un peu long, mais je pense que c'est la façon la 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 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);
}
#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 existe de nombreuses autres informations utiles que vous pouvez obtenir en utilisant termcap. Consultez le manuel termcap à l'aide de info termcap
pour plus de détails.
Si ncurses est installé et que vous l'utilisez, vous pouvez utiliser getmaxyx()
pour trouver les dimensions du terminal.
Donc, ne suggérant 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.
Il semble que le terminal GNOME crée lui-même ces variables d'environnement?
En supposant que vous êtes sous Linux, je pense que vous souhaitez utiliser la bibliothèque ncurses à la place. Je suis à peu près sûr que le contenu que vous avez n'est pas dans stdlib.