Estou procurando uma maneira de obter a largura do terminal de dentro do meu programa C. O que eu continuo descobrindo é algo como:
#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);
}
Mas toda vez que tento eu consigo
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.)
Esta é a melhor maneira de fazer isso ou existe uma maneira melhor? Se não, como posso fazer isso funcionar?
EDIT: código fixo é
#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;
}
Respostas:
Você já pensou em usar getenv () ? Ele permite que você obtenha as variáveis de ambiente do sistema que contêm as colunas e linhas dos terminais.
Como alternativa, usando seu método, se você quiser ver o que o kernel vê como o tamanho do terminal (melhor no caso de o terminal ser redimensionado), você precisará usar TIOCGWINSZ, ao contrário de TIOCGSIZE, assim:
e o código completo:
fonte
ws_xpixel
ews_ypixel
, mas só imprime zeros!Este exemplo é um pouco extenso, mas acredito que seja a maneira mais portátil de detectar as dimensões do terminal. Isso também lida com eventos de redimensionamento.
Como tim e rlbond sugerem, estou usando ncurses. Isso garante uma grande melhoria na compatibilidade do terminal em comparação com a leitura direta de variáveis de ambiente.
fonte
man 7 signal
OK
eERR
. Quão "gentis" eles nos ajudaram a preencher essa lacuna em nossas vidas :-(Precisa ser compilado com
-ltermcap
. Existem muitas outras informações úteis que você pode obter usando o termcap. Verifique o manual do termcap usandoinfo termcap
para mais detalhes.fonte
Se você tiver ncurses instalado e estiver usando, você pode usar
getmaxyx()
para encontrar as dimensões do terminal.fonte
Supondo que você esteja no Linux, acho que você deseja usar a biblioteca ncurses . Tenho certeza de que o ttysize que você tem não está no stdlib.
fonte
ioctl
jeito é mais simples e limpo, porque você não precisa inicializar curses, etc.Portanto, não estou sugerindo uma resposta aqui, mas:
linux-pc:~/scratch$ echo $LINES
49
linux-pc:~/scratch$ printenv | grep LINES
linux-pc:~/scratch$
Ok, e notei que se eu redimensionar o terminal GNOME, as variáveis LINES e COLUMNS seguem isso.
Parece que o terminal GNOME está criando essas variáveis de ambiente sozinho?
fonte
Para adicionar uma resposta mais completa, o que descobri que funciona para mim é usar a solução de @John_T com alguns bits adicionados do Rosetta Code , junto com alguma solução de problemas para descobrir dependências. Pode ser um pouco ineficiente, mas com a programação inteligente você pode fazer funcionar e não abrir o arquivo do terminal o tempo todo.
Se você se certificar de não chamar tudo, mas talvez de vez em quando você fique bem, ele deve até atualizar quando o usuário redimensiona a janela do terminal (porque você está abrindo o arquivo e lendo-o a cada ).
Se você não estiver usando,
TIOCGWINSZ
veja a primeira resposta neste formulário https://www.linuxquestions.org/questions/programming-9/get-width-height-of-a-terminal-window-in-c-810739/ .Ah, e não se esqueça
free()
doresult
.fonte
Aqui estão as chamadas de função para a variável ambiental já sugerida:
fonte
SIGWINCH
sinal, para que possam manter as variáveis atualizadas (eles também precisam disso para fazer a quebra de linha apropriada no editor de entrada).getenv()
retorna NULL ou não e isso acontece no meu terminal Linux (porque essas variáveis não são exportadas.) Além disso, mesmo se o shell atualizar essas variáveis, você não verá o muda enquanto seu programa está sendo executado (não sem você ter seu próprioSIGWINCH
manipulador).