programing

터미널 폭(C)을 얻고 있습니까?

javaba 2022. 8. 1. 23:36
반응형

터미널 폭(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
}

좀 더 완전한 답변을 덧붙이자면, 나에게 도움이 되는 것은 @John_을 사용하는 것입니다.Rosetta Code에서 일부 비트가 추가된 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;
}

모든 것을 호출하지 않도록 하고, 경우에 따라서는 문제가 없을지도 모릅니다.또한 사용자가 터미널 창의 크기를 조정할 때 업데이트해야 합니다(파일을 열어 읽을 때마다 파일을 읽기 때문입니다).

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

오, 그리고 잊지 말고free()result.

이 예는 다소 장황한 편이지만 터미널 치수를 검출하는 가장 휴대성이 높은 방법이라고 생각합니다.크기 조정 이벤트도 처리합니다.

팀이랑 릴본드가 말해주듯 난 엔커스를 쓰고 있어환경 변수를 직접 읽는 것에 비해 단말기 호환성이 크게 향상되었습니다.

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

컴파일 대상-ltermcaptermcap을 사용하여 얻을 수 있는 기타 유용한 정보가 많이 있습니다.다음을 사용하여 용어 상한 설명서를 확인하십시오.info termcap자세한 것은, 을 참조해 주세요.

ncurses가 설치되어 있고 사용 중인 경우,getmaxyx()터미널의 치수를 알아냅니다.

당신이 Linux에 있다고 가정한다면, 나는 당신이 대신 ncurses 라이브러리를 사용하길 원한다고 생각합니다.당신이 가지고 있는 티사이즈 물건은 stdlib에 없는 것이 확실합니다.

그래서 여기서 답을 제안하는 것이 아니라,

linux-pc:~/scratch$ echo $LINES

49

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

linux-pc:~/scratch$

네, GNOME 터미널 크기를 조정하면 LINES 변수와 COLUMNS 변수가 그 뒤를 따릅니다.

GNOME 단말기가 환경변수 자체를 만들어 내는 것 같나요?

다음은 이미 제안된 환경변수에 대한 함수 호출입니다.

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

언급URL : https://stackoverflow.com/questions/1022957/getting-terminal-width-in-c

반응형