[c] C에서 터미널 너비를 얻습니까?

내 C 프로그램 내에서 터미널 너비를 얻는 방법을 찾고 있습니다. 내가 계속 생각하는 것은 다음과 같은 것입니다.

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

하지만 내가 시도 할 때마다

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 %d\n", w.ws_row);
    printf ("columns %d\n", w.ws_col);
    return 0;
}



답변

getenv () 사용을 고려해 보셨습니까? ? 터미널 열과 행을 포함하는 시스템의 환경 변수를 가져올 수 있습니다.

또는 방법을 사용하여 커널이 터미널 크기로 보는 것을보고 싶다면 (터미널 크기가 조정 된 경우 더 좋음) 다음과 같이 TIOCGSIZE가 아닌 TIOCGWINSZ를 사용해야합니다.

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
}


답변

이 예제는 약간 긴 편이지만 터미널 치수를 감지하는 가장 이식 가능한 방법이라고 생각합니다. 이것은 또한 크기 조정 이벤트를 처리합니다.

tim과 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합니다. termcap을 사용하여 얻을 수있는 다른 유용한 정보가 많이 있습니다. info termcap자세한 내용 은 termcap 설명서를 확인 하십시오.


답변

ncurses가 설치되어 있고 사용중인 경우을 사용 getmaxyx()하여 터미널의 크기를 찾을 수 있습니다 .


답변

Linux를 사용한다고 가정하면 대신 ncurses 라이브러리 를 사용하고 싶습니다 . 나는 당신이 가지고있는 ttysize 물건이 stdlib에 없다고 확신합니다.


답변

따라서 여기에 답변을 제안하지는 않지만 :

linux-pc:~/scratch$ echo $LINES

49

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

linux-pc:~/scratch$

좋습니다. GNOME 터미널의 크기를 조정하면 LINES 및 COLUMNS 변수가 그 뒤에옵니다.

GNOME 터미널이 이러한 환경 변수 자체를 생성하는 것처럼 보입니다.


답변

더 완전한 답변을 추가하기 위해 내가 찾은 것은 Rosetta Code 에서 추가 된 일부 비트와 함께 @John_T의 솔루션을 사용 하고 종속성을 파악하는 문제를 해결하는 것입니다. 약간 비효율적 일 수 있지만 스마트 프로그래밍을 사용하면 항상 터미널 파일을 열지 않고 작동하도록 만들 수 있습니다.

#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h> // ioctl, TIOCGWINSZ
#include <err.h>       // err
#include <fcntl.h>     // open
#include <unistd.h>    // close
#include <termios.h>   // don't remember, but it's needed

size_t* get_screen_size()
{
  size_t* result = malloc(sizeof(size_t) * 2);
  if(!result) err(1, "Memory Error");

  struct winsize ws;
  int fd;

  fd = open("/dev/tty", 0_RDWR);
  if(fd < 0 || ioctl(fd, TIOCGWINSZ, &ws) < 0) err(8, "/dev/tty");

  result[0] = ws.ws_row;
  result[1] = ws.ws_col;

  close(fd);

  return result;
}

모든 것을 호출하지 않고 가끔씩은 괜찮을 것입니다. 사용자가 터미널 창 크기를 조정할 때 업데이트해야합니다 (파일을 열고 매번 읽을 수 있기 때문입니다 ).

사용하지 않는 경우 https://www.linuxquestions.org/questions/programming-9/get-width-height-of-a-terminal-window-in-c-810739/TIOCGWINSZ 양식에서 첫 번째 답변을 참조하십시오 .

아, 그리고 잊지 마세요 .free()result