Ir ao conteúdo

Posts recomendados

Postado

Boa noite.

Queria tirar uma dúvida: estou no windows, tentei usar system() para limpar a tela, mas não funciona.

O algoritmo não importa, testei um que era pra funcionar mas nada acontece, nem aparece mensagem de erro.

Alguém tem alguma ideia do que poderia causar isso?

Sim, estou usando a biblioteca stdlib.h, também testei com a cstdlib. E sim, já testei system("cls"), system("CLS"), system("clear"), etc.

  • Curtir 1
Postado

@herbertbahia To com o CodeBlocks e o Dev instalados, mas só uso o CodeBlocks.

Esse clrscr() serve só pra jogar um monte de \n, não é isso? De qualquer forma, queria mesmo o system().

PS: quando eu compilo, aparece um erro dizendo que clrscr() não está declarado, mesmo usando o conio.h.

  • Curtir 2
Postado

@vangodp Não é que eu não me importei em verificar... É que eu já tava frustrado com esse dev.

A gente ficou falando desse problema durante uns 3 dias. Desisti e instalei o CodeBlocks (que compilou e executou tudo certinho).

 

Mais tarde eu entro nesse discord aí pra gastar mais algumas horas e não conseguir resolver nada como de costume... kk

PS: O problema não é você, eu que sou azarado mesmo. Mas, de qualquer forma, obrigado por tentar me ajudar.

  • Curtir 1
Postado
Em 19/04/2020 às 21:32, Lucca Rodrigues disse:

De qualquer forma, queria mesmo o system().

PS: quando eu compilo, aparece um erro dizendo que clrscr() não está declarado, mesmo usando o conio.h

 

Usar system() para fazer algo em um programa não é de fato fazer algo. system() apenas pega uma string e envia para o interpretador de comandos. E não é um boa ideia. E não é nada ativo, apenas um intermediário. E é algo que você simplesmente não pode e não quer fazer em muitos ambientes, Se alguém injetar um executável com o nome de seu comando ou pior, o nome do seu script, imagine o que pode acontecer com seu computador, seu contrato ou seu emprego...

 

Use as funções do sistema para fazer o que precisa. Usar system() é como explicar o caminho para alguém só que fazendo aquela cara de professor e indicando o Google Maps ou o Waze 

 

Um pouco de história em tempos de confinamento

 

 

 Limpar a tela na "console" do Linux 
 

Isso é algo controvertido: no Unix / Linux não existe console. E não há modo limpar a tela. E porque não? O terminal no Linux é um arquivo. Uma emulação de um terminal da Digital dos anos 70. VT-100 em geral. Algo que tinha uma tela, teclado e tomada. 

 

Olha um aqui:
 

vt-100.jpg.709b4e34b94d550fb9ea2c19b13f02ca.jpg

 

Esse aí na verdade. No manual dele estão todos os comandos ESC [ xx yy ; que são usados ainda hoje. E não havia esse conceito de limpar a tela porque os caracteres eram lidos e  escritos um a um pelo sistema. Todos os terminais ficavam ligados ao sistema por um adaptador serial com uma porta para cada terminal. onde você ligava o cabo, até uns 50m. Mais longe? Usava um modem e uma linha telefônica. Esse era o terminal remoto.
 

Uma maneira simples de limpar a tela então era identificar quantas linhas tinha a sua tela e enviar tantos \n quantas linhas tivesse lá, e aí o texto sumia, claro. Sério. E se aparecia tudo meio estranho eis o que a gente fazia: desligava o cara e ligava de novo. Ele não tinha memória do que estava na tela.

 

A console era em geral o terminal 0, /dev/tty0, e só tinha valor porque quando tinha um problema maior talvez o sistema escrevesse algo lá além de acender umas luzes no painel de controle. De resto era um terminal como outro qualquer.

 

Nos tempos pós 80 os terminais são emulados por programas, como xterm, que filtram o que vai para a "console". O mais perto de limpar a tela seria enviar um comando tput reset para o "terminal". Isso seria o equivalente a ligar o cara de novo se ele fosse de verdade. O que será enviado para o terminal está codificado num tipo de banco de dados chamado terminfo e que foi uma novidade muito legal quando apareceu... 

 

Direto do manual:

 

image.png.725325a1a9473a8ade224b3168553701.png

E é exatamente isso: como os terminais eram ligados via porta serial, você podia enviar um comando para ele e esperar algum tipo de resposta dizendo que terminal está lá. A maioria deles respondia a um ESC qualquer coisa com a marca e modelo e alguns recursos. E era um inferno porque era preciso ficar questionando cada terminal, e se não viesse resposta já era. Um pesadelo. Com terminfo era só verificar um variável de ambiente e a partir daí pegar os comandos lá no terminfo. Claro que você pode acessar vários tty ao mesmo tempo. tty vem de teletype que é como os terminais era ANTES de serem emuladores e ANTES de terem telas. Veja um comum, o LA36:
 

la36.png.a9da08f42182047eede5d9ac3fe6443a.png

 

podia usar 132 colunas, tinha minúsculas! e podia até usar o modo gráfico! Ruim era por a cadeira na frente e acabar pisando no formulário...

 

Limpar a tela na console do Windows

 

Aí é uma outra história. O Windows tem uma imagem do que está na tela da console, e você pode ter mais de uma associada a um programa, embora eu nunca tenha visto alguém usar isso. enviar um certo número de newlines também serviria, mas veja o padrão de linhas da console do Windows:
 

console-win.png.193f93ac99fbed8ff3f3661e6ccc12b8.png

 

Sim. 9001 Linhas. O oficial para limpar a tela no Windows é simplesmente rodar as funções da console, bem documentadas em https://docs.microsoft.com/en-us/windows/console/console-reference. Ao menos eu acho que estão bem documentadas.

 

Uma versão de cls() pelo oficial da console do Windows seria algo assim:


int		cls()
{	// limpa a tela no windows, do jeito oficial
	CONSOLE_SCREEN_BUFFER_INFO		info;
	HANDLE		H = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD		origem = { 0,0 };
	int			total;
	if (H == INVALID_HANDLE_VALUE) return -1;
	GetConsoleScreenBufferInfo(H, &info);
	int r = FillConsoleOutputCharacter(H, (TCHAR)' ',
		info.dwSize.X * info.dwSize.Y,
		origem, &total);
	int s = FillConsoleOutputAttribute(
		H, info.wAttributes,
		info.dwSize.X * info.dwSize.Y,
		origem, &total);
	SetConsoleCursorPosition(H, origem);
	return 0;
};	// end cls()

Bem claro: 

  • vê o tamanho da tela
  • preenche tudo com brancos
  • coloca o cursor lá no começo.

No entanto isso não é mais recomendado: o certo hoje em dia em tempos de Microsfot Azure, Google Cloud e Amazon AWS  em que os computadores estão todos indo para a nuvem inclusive os terminais dos alunos, o recomendado é usar o Terminal do Windows que usa aceleração por hardware e é compatível com o xterm...

 

Como aparece no link em todas as consoles Windows desde 2017
 

image.png.b79b3ec4343d2e64aba74c1bd03ee89b.png

 

 

 

 

 

image.png

image.png

image.png

  • Curtir 3
  • Obrigado 1
Postado

@arfneto

6 minutos atrás, arfneto disse:

Usar system() para fazer algo em um programa não é de fato fazer algo. system() apenas pega uma string e envia para o interpretador de comandos. E não é um boa ideia. E não é nada ativo, apenas um intermediário. E é algo que você simplesmente não pode e não quer fazer em muitos ambientes, Se alguém injetar um executável com o nome de seu comando ou pior, o nome do seu script, imagine o que pode acontecer com seu computador, seu contrato ou seu emprego...

Já tinha ouvido falar que usar esse system() é ruim, e realmente eu não tava querendo usar não, eu preferia usar um laço pra gerar um monte de \n mesmo, é um jeito meio besta mas também funciona, mas meu professor não aceitou...

  • Curtir 1
Postado
8 minutos atrás, Lucca Rodrigues disse:

á tinha ouvido falar que usar esse system() é ruim, e realmente eu não tava querendo usar não, eu preferia usar um laço pra gerar um monte de \n mesmo, é um jeito meio besta mas também funciona, mas meu professor não aceitou...

 

O código que eu te mostrei é o simples, de acordo com a documentação. 

int		cls()
{	// limpa a tela no windows, do jeito oficial
	CONSOLE_SCREEN_BUFFER_INFO		info;
	HANDLE		H = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD		origem = { 0,0 };
	int			total;
	if (H == INVALID_HANDLE_VALUE) return -1;
	GetConsoleScreenBufferInfo(H, &info);
	int r = FillConsoleOutputCharacter(H, (TCHAR)' ',
		info.dwSize.X * info.dwSize.Y,
		origem, &total);
	int s = FillConsoleOutputAttribute(
		H, info.wAttributes,
		info.dwSize.X * info.dwSize.Y,
		origem, &total);
	SetConsoleCursorPosition(H, origem);
	return 0;
};	// end cls()

E tem até o mesmo nome. Não serve para seu caso?

 

Essa é a maneira oficial:

  • Chama GetConsoleScreenBufferInfo() para saber o tamanho atual da tela, que é variável.
  • Chama FillConsoleOutputCharacter() e FillConsoleOutputAttribute() para limpar os caracteres E atributos porque são coisas separadas
  • E põe o cursor em (0,))

 

 

adicionado 44 minutos depois

você entendeu que basta colocar essa função cls() em seu programa em C? Se for C++ tem um jeito mais certo, mas assim também funciona. 

 

E esse é o jeito certo, de acordo com a Microsoft. Esse seu professor não pode recusar. 

  • Curtir 1
  • Obrigado 1
Postado

@arfneto Acho que fiz algo errado...

 

image.png.b8f93e5d8cbb1f4412d1e0cb0e604734.png

 

Em 20/04/2020 às 16:22, arfneto disse:

 


int		cls()
{	// limpa a tela no windows, do jeito oficial
	CONSOLE_SCREEN_BUFFER_INFO		info;
	HANDLE		H = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD		origem = { 0,0 };
	int			total;
	if (H == INVALID_HANDLE_VALUE) return -1;
	GetConsoleScreenBufferInfo(H, &info);
	int r = FillConsoleOutputCharacter(H, (TCHAR)' ',
		info.dwSize.X * info.dwSize.Y,
		origem, &total);
	int s = FillConsoleOutputAttribute(
		H, info.wAttributes,
		info.dwSize.X * info.dwSize.Y,
		origem, &total);
	SetConsoleCursorPosition(H, origem);
	return 0;
};	// end cls()

 

 

Depois disso, não era só chamar o cls() no main?

  • Curtir 1
Postado

talvez você deva postar o código pra eu poder ajudar

Não há nada errado com cls()

 

adicionado 0 minutos depois

Que compilador você usa? Usa um IDE? sabe usar só o compilador? Que versão é? Qual a versão do windows? Só pra eu saber melhor do que estamos falando

adicionado 2 minutos depois

Você mexeu nas opções de compilação? pode ter deixado muito restritivo, tipo /WX...

adicionado 9 minutos depois

image.thumb.png.97a662f1a356b96c78ef967107d0a43c.png

 

Em https://github.com/ARFNeto-CH/console_stuff baixe esse programa. Tem várias funções que pode querer usar. E certamente roda em Windows. Rode esse como teste para saber se o ambiente está ok.

 

Ele tem

  • uma implementação de peek() para ler da console sem ler de verdade
  • uma função que escreve em vídeo reverso  invertendo de fato as cores em uso no momento
  • uma rotina que posiciona o cursor em linha e coluna, como os não matemáticos esperam
  • e talvez outras coisas de que não me lembro

E tem que sair como está abaixo

 

image.thumb.png.c6177d1042c5a6db82d39313a2c18a65.png

  • Curtir 1
Postado

O problema do #13 era sim a falta do include ;) 

 

  • Isso que acontece na máquina é um problema do compilador ou do IDE?
  • Que compilador está em uso?
  • Só tem uma versão? Instalou outras? Esse Dev-C++ inclui o gcc 5.2. Instalou o 8.2? O CL? Testou com os 3? 
  • Testou o programa que enviei, sem mudar uma linha?
     
    50 minutos atrás, vangodp disse:

    Pode estar alguma DLL corrupta. Ou a API sei lá.

Não deve ser o caso. 

  • Curtir 1
Postado
8 minutos atrás, vangodp disse:

O problema dele é limpar a copiar um tela.

 

entenda que antes não havia o include, como ele mesmo disse.

 

Gere o programa em outra máquina e rode lá para ver o que acontece. E procure por alguma sacanagem como alguém ter criado um executável system só para criar polêmica. Mande executar alguma outra coisa inofensiva como "MKDIR %TEMP%\TESTE" usando system() e veja se cria.

 

e assim que funcionar não use nunca mais. system() é uma bobagem. Chamar o shell para fazer algo é algo ingênuo e arriscado.

 

Se precisarem de mim posso acessar a máquina remotamente em algum horário em que eu tenha tempo. Esses tempos de confinamento mudaram bem a minha agenda...
 

Boa sorte

 

 

  • Curtir 2
Postado
1 hora atrás, vangodp disse:

por exemplo uma função chamada system o algo dentro da pasta system32? Ou ter uma rota no path do sistema...algo pelo estilo?

 

Isso. Algo assim. Ou coisas como um CLS.EXE no lugar certo. Testou com o "mkdir %TEMP%\teste" ?

Rodou com  dois gcc na linha de comando e nenhum dos dois rodou o código? Nem mesmo esse que eu falei? 🤔

adicionado 1 minuto depois

E esse console_stuff que eu escrevi. Sem mudar uma linha, não roda? Ele usa muitas e muitas funções da mesma biblioteca

  • Curtir 1

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...