Получение ширины терминала В C?



Я искал способ получить ширину терминала из моей программы C. То, что я продолжаю придумывать, это что-то вроде:



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

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

printf ("lines %dn", ts.ts_lines);
printf ("columns %dn", ts.ts_cols);
}


но каждый раз, когда я пытаюсь это я получаю



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.)


Это лучший способ сделать это, или есть лучший способ? Если нет, то как я могу заставить это работать?



изменить: исправлен код



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

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

printf ("lines %dn", w.ws_row);
printf ("columns %dn", w.ws_col);
return 0;
}
885   6  

6 ответов:

вы рассматривали использование getenv () ? Это позволяет получить переменные среды системы, которые содержат столбцы и строки терминалов.

в качестве альтернативы, используя Ваш метод, если вы хотите увидеть, что ядро видит как размер терминала (лучше в случае изменения размера терминала), вам нужно будет использовать TIOCGWINSZ, в отличие от вашего TIOCGSIZE, например:

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

и весь код:

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

этот пример немного длинноват, но я считаю, что это самый портативный способ обнаружения размеров терминала. Это также обрабатывает события изменения размера.

как Тим и rlbond предлагает, я использую ncurses. Это гарантирует значительное улучшение совместимости терминалов по сравнению с непосредственным чтением переменных среды.

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

должен быть скомпилирован с -ltermcap . Есть много другой полезной информации вы можете получить с помощью терминала. Проверьте в руководстве пользователя терминала, используя info termcap для более подробной информации.

Если у вас есть ncurses установлены и используют его, вы можете использовать getmaxyx() чтобы найти размеры терминала.

предполагая, что вы находитесь на Linux, я думаю, что вы хотите использовать ncurses библиотека вместо. Я почти уверен, что ttysize вещи у вас есть не в stdlib.

вот вызовы функции для уже предложенной переменной окружающей среды:

int lines = atoi(getenv("LINES"));
int columns = atoi(getenv("COLUMNS"));

Comments

    Ничего не найдено.