質問

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変数がそれに続きます。

KindaはGNOME端末がこれらの環境変数自体を作成しているようです?

すでに提案されている環境変数の関数呼び出しは次のとおりです。

int lines = atoi(getenv("LINES"));
int columns = atoi(getenv("COLUMNS"));
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top