-
Posts
6.526 -
Cadastrado em
-
Última visita
Tipo de conteúdo
Artigos
Selos
Livros
Cursos
Análises
Fórum
Tudo que arfneto postou
-
Não entendi. Continua errado
-
Não entendi quase nada da discussão, mas o que posso dizer é que C e C++ são linguagens muito distintas. C++ é uma linguagem enorme e com muitas facilidades. C é uma linguagem bem compacta e gera programas compactos e muito, muito rápidos. E é trivial mixar código compilado escrito em C e C++ e assim se economiza tempo e dinheiro hoje em dia. A Solucão Concreta Você declarou char arquivo[120]; E assim arquivo é do tipo char* Por outro lado você escreveu na tal linha 40 fprintf(arquivo,"Nome do cliente: ",Cliente.nome); E printf() é declarada int printf(FILE* stream, const char* format, ...); E o compilador não sabe como converter char* para FILE* E você declarou FILE *Dados_Cliente; E deveria ter escrito fprintf(Dados_Cliente, "Nome do cliente: ",Cliente.nome); Reclamação concreta: como a listagem do programa não tem números de linha, você bem que poderia ter dito qual a linha 40 e eu teria economizado uns 90s adicionado 12 minutos depois printf("Digite o celular do cliente: "); scanf("%f",Cliente.celular); fprintf(Dados_Cliente,"Celular: %f\n",Cliente.celular); printf("Digite o telefone fixo do cliente: "); scanf("%f",Cliente.fixo); fprintf(Dados_Cliente,"Fixo: %f\n",Cliente.fixo); E aqui sua estrutura Cliente é estática então deve usar ponto para acessar os campos e & para referenciar os endere;cos que scanf() espera... Apenas use &Cliente.celular e &Cliente.fixo float para esse tipo de dados é estranho hein? o normal é algo da forma +ccc (aaa) nnnn-nnnn-nnnn e por isso se usa em geral uma string ou mesmo uma classe com os campos de código de país, código de área e número separados, no formato de string. E se aceita separadores porque cada um tem um costume, e letras no "número", porque muita gente memoriza ou anota os números por letra em muitos países. Aqui só me lembro do 333 PORTO da seguradora. E isso é oficial: E.161 : Arrangement of digits, letters and symbols on telephones and other devices that can be used for gaining access to a telephone network
-
@devair1010 acho que entendeu que não era pra ver mais o que faz ali. Eu tinha apagado uma boa parte do código e esqueci essas linhas. Achei difícil de ler. Acho que sabe de onde vem os asteriscos agora. Não disse o que acontece com esse outro compilador... O que passa afinal? Isso não deveria ter diferença em Windows. Como sabe eu postei uma tela do resultado. Mas isso é mesmo um inferno mesmo, programas para a console no Windows. E um inferno no Linux, ou quase, porque não tem console nem nada. E já foi muito pior até o Unix criar o terminfo. Pode depender no Windows de como a console está configurada, ou da particular versão de Windows, mas não deveria fazer diferença o compilador. Como eu já disse aqui sobre esses programas, é muito melhor usar o novo terminal do windows, que é mais confiável e usa a aceleração da placa de vídeo
-
Programou o Merge Sort já? Comece por isso e poste o código aqui. Depois disso você implementa threads. Não acrescenta muito já que vão rodar o mesmo código e pela definição do algoritmo de sort não há interferência entre as áreas de memória a classificar.
-
char* barra = (char*)malloc(1 + sizeof(char) * colunas); memset(barra, c, colunas); *(colunas + barra) = 0; // termina a string /* de onde veio os Asteriscos da barra ? */ @devair1010 A origem dos asteriscos borda('*'); //trata-se do argumento ao chamar void borda(char); Não são asteriscos. Trata-se do parâmetro c na chamada de memset() A verdade sobre o programa Eu escrevi um programa mínimo para mostrar a maneira oficial usando as funções de console do windows. Mas aí a função mostra tinha mais dois parâmetros, um int e um char, e ela desenhava n bordas coloridas com um char em torno da mensagem centralizada na tela. Só que na hora de postar achei muito complicado para um iniciante ler e apaguei essa parte toda. E aí sumiu por exemplo o asterisco no protótipo Esses comandos printf("\n\n Buffer: %d linhas, %d colunas em Console Windows\n", info.dwSize.Y, info.dwSize.X); printf(" Viewport: upper-left: (%d,%d) bottom-right: (%d,%d) = (%d,%d)\n", info.srWindow.Top, info.srWindow.Left, info.srWindow.Bottom, info.srWindow.Right, linhas, colunas ); tinham outro char c = getc(stdin); depois. Então era pra ter apagado TUDO e esqueci desses printf(). Tinha mais na verdade, porque eu mostrava a estrutura info toda porque entender aquilo é essencial para entender como a console funciona no Windows. E Sleep() não serviria porque não se sabe quando tempo o cara vai levar para ler os valores todos. E acho que já sabe que Sleep() não é confiável e pode ser interrompida, o que é algo bem engraçado Pode escrever mostra() assim void mostra(char* texto) { HANDLE H = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_SCREEN_BUFFER_INFO info; GetConsoleScreenBufferInfo(H, &info); int linhas = info.srWindow.Bottom - info.srWindow.Top + 1; // altura da parede int colunas = info.srWindow.Right - info.srWindow.Left + 1; // largura da parede int largura = strlen(texto); int centroL = linhas / 2; // altura do quadro int centroC = colunas / 2 - largura/2; // distancia da margem da parede text_color(_branco_, _preto_); gotoYX(centroL, centroC); // posiciona printf("%s", texto); // mostra o texto char c = getc(stdin); return; }; // mostra() Claro que não precisava dessas variáveis todas mas é um exemplo para iniciantes O asterisco estava faltando mesmo porque cortei a mais quando apaguei os outros parâmetros quando a mostra() era mais "circense" digamos e escrevia as n bordas coloridas . Meu compilador aceitou porque de todo modo ela está declarada depois e o linker acabou resolvendo a referência, mas devia mesmo ter dado erro Eu fiquei curioso por esse lance do compilador de que falou. Isso não pode dar erro em Windows. O que aconteceu? Eu me comprometi a não usar as máquinas Linux e não usar outros compiladores quando comecei a postar neste forum, mas estou quase instalando esse outro. Onde arrumo essa versão se eu resolver instalar isso? O programa de teste de novo #define _CRT_SECURE_NO_WARNINGS #define _preto_ 0 #define _azul_ 1 #define _verde_ 2 #define _ciano_ 3 #define _vermelho_ 4 #define _magenta_ 5 #define _marron_ 6 #define _cinza_claro_ 7 #define _cinza_escuro_ 8 #define _azul_claro_ 9 #define _verde_claro_ 10 #define _ciano_claro_ 11 #define _vermelho_claro_ 12 #define _magenta_claro_ 13 #define _amarelo_ 14 #define _branco_ 15 #define textcolor_2( letras, fundo) \ SetConsoleTextAttribute( \ GetStdHandle(STD_OUTPUT_HANDLE), \ (letras|(fundo<<4)) \ ) #include <stdio.h> #include <windows.h> void borda(char); void cls(); void gotoYX(int, int); void mostra(char*); void text_color(int, int); int main(int argc, char** argv) { cls(); borda('*'); mostra("Bem no meio da tela"); }; // main() void borda(char c) { // desenha o caracter c em toda a borda da console // para testar os limites. Nao usa a ultima linha HANDLE H = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_SCREEN_BUFFER_INFO info; GetConsoleScreenBufferInfo(H, &info); int linhas = 1 - info.srWindow.Top + info.srWindow.Bottom; int colunas = 1 + info.srWindow.Right - info.srWindow.Left; char* barra = (char*)malloc(1 + sizeof(char) * colunas); memset(barra, c, colunas); *(colunas + barra) = 0; // termina a string cls(); gotoYX(0, 0); printf("%s\n", barra); for (int i = 1; i < linhas - 2; i++) { gotoYX(i, 0); printf("*"); gotoYX(i, colunas - 1); printf("*"); } gotoYX(linhas - 2, 0); printf("%s\n", barra); free((void*)barra); return; }; // borda() void 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; 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; }; // cls() void gotoYX(int linha, int coluna) { HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE); static COORD coord; coord.X = coluna; coord.Y = linha; SetConsoleCursorPosition(console, coord); return; }; // gotoYX() void mostra(char* texto) { HANDLE H = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_SCREEN_BUFFER_INFO info; GetConsoleScreenBufferInfo(H, &info); int linhas = info.srWindow.Bottom - info.srWindow.Top + 1; // altura da parede int colunas = info.srWindow.Right - info.srWindow.Left + 1; // largura da parede int largura = strlen(texto); int centroL = linhas / 2; // altura do quadro int centroC = colunas / 2 - largura/2; // distancia da margem da parede text_color(_branco_, _preto_); gotoYX(centroL, centroC); // posiciona printf("%s", texto); // mostra o texto char c = getc(stdin); return; }; // mostra() void text_color(int letras, int fundo) { SetConsoleTextAttribute( GetStdHandle(STD_OUTPUT_HANDLE), letras | (fundo << 4) ); } // text_color
-
Você entendeu o que eu expliquei @yuri_carneiro? De volta ao tópico: Escrever texto centralizado na tela não tem muito a ver com programação e sim com aritmética. É a mesma coisa que chegar em uma sala para pendurar um quadro na parede: você vai lá e mede a parede mede o quadro faz as contas coloca um prego na posição certa pendura o quadro Como medir a janela da console do Windows? Pergunte ao Windows, 3 linhas: HANDLE H = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_SCREEN_BUFFER_INFO info; GetConsoleScreenBufferInfo(H, &info); Você declara essa variável H para pegar o endereço da console em que seu programa está rodando e declara essa estrutura info aí. Elá é assim, como está no manual: typedef struct _CONSOLE_SCREEN_BUFFER_INFO { COORD dwSize; COORD dwCursorPosition; WORD wAttributes; SMALL_RECT srWindow; COORD dwMaximumWindowSize; } CONSOLE_SCREEN_BUFFER_INFO; Aí você chama essa rotina GetConsoleScreenBufferInfo() e ela faz a gentileza de preencher essa tal info com os valores certos. Isso porque enquanto seu programa está rodando alguém pode ir lá e mudar o tamanho da console. Não vou explicar tudo de novo como está no manual, mas em resumo wAttributes tem os valores de cor das letras e cor de fundo em uso. Se não vai mudar, esqueça dwSize tem o tamanho da janela e é bem maior em geral que a que está na tela. Você pode ver nas propriedades da janela do prompt de comando do Windows e em geral é de 120 colunas por 9001 linhas porque assim você pode rolar a janela para textos que já saíram da tela. Veja essa no computador que estou usando agora: Isso quer dizer que a janela da console tem 40 linhas de 120 colunas no momento srWindow Essa é a parte da janela que está na tela no momento e é aí que você vai escrever seu texto, no modo simples de fazer. E essa p$%%a de COORD? Bem, assim é como são guardadas as coordenadas na console do windows. Direto do manual: typedef struct _COORD { SHORT X; SHORT Y; } COORD; E é só isso: coluna e linha. Sim isso é um porre porque (x,y) é a notação para um gráfico cartesiano por exemplo, com x no eixo horizontal e y na vertical. Só que na tela você espera ver linha e coluna, o contrário. E é só isso. Em info vem tudo preenchido então antes de escrever você "mede a parede": int linhas = info.srWindow.Bottom - info.srWindow.Top + 1; // altura da parede int colunas = info.srWindow.Right - info.srWindow.Left + 1; // largura da parede Se o seu texto está em char* texto: você "mede o quadro" int largura = strlen(texto); E aí calcula onde vai escrever, linha e coluna. "Faz as contas": int centroL = linhas / 2; // altura do quadro int centroC = colunas / 2 - largura/2; // distancia da margem da parede "Põe o prego" gotoYX(centroL, centroC); // posiciona Essa rotina gotoYX() não é necessária e acaba atrapalhando, já expliquei isso antes. Mas não vou ficar insistindo. Apenas entenda que ao aceitar usar essa gotoxy() que circula desde os anos 80 vai acabar tendo que toda vez ficar invertendo esses valores, como eu expliquei e o @devair1010 te falou. E vai ficar longe das funções que na verdade fazem o mesmo trabalho e que são o padrão dos programas que você vai encontrar fora desses foruns E se a função foi escrita a partir das funções do Windows porque diabo não inverter logo isso e usar linha e coluna? Então vou deixar um exemplo de uma void gotoYX(int linha, int coluna); que ao menos faz mais sentido porque você passa logo linha e coluna na ordem. É bem simples. Veja: void gotoYX(int linha, int coluna) { HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE); static COORD coord; coord.X = coluna; coord.Y = linha; SetConsoleCursorPosition(console, coord); return; }; // gotoYX() Note que a função SetConsoleCursorPostion() é a que movimenta o cursor na console no Windows. "Pendurar o quadro" printf("%s", texto); // mostra o texto Pois é. Só isso. O printf() imprime o texto na posição certa, depois do que a gente calculou Programar a console é complexo e não compensa a menos que seja um curso ou um início de aprendizado OU você não tenha mesmo uma interface gráfica. Ao usar essas coisas em geral você vai ter que manter uma imagem da tela toda na memória e desenhar a tela de novo toda hora para ter mais controle sobre o que está lá text_color e as cores como você vê em todo canto nesses forums parece haver uma tendência em manter viva essa função text_color() ou mesmo ressuscitar a mesma na forma de text_color_2() e é uma função besta que você chama com a cor das letras e a cor de fundo que quer usar e ela tem efeito imediato. De onde vem isso? Agora você já sabe: é o valor de wAttributes naquela estrutura info. Postei um programa que gera um gabarito para esses valores e que você pode copiar. Não sei agora o tópico mas é só pesquisar no forum o que eu postei nos últimos dias. De todo modo eis as constantes que importam, e uma própria text_color_2() mais resumida que eu escrevi #define _preto_ 0 #define _azul_ 1 #define _verde_ 2 #define _ciano_ 3 #define _vermelho_ 4 #define _magenta_ 5 #define _marron_ 6 #define _cinza_claro_ 7 #define _cinza_escuro_ 8 #define _azul_claro_ 9 #define _verde_claro_ 10 #define _ciano_claro_ 11 #define _vermelho_claro_ 12 #define _magenta_claro_ 13 #define _amarelo_ 14 #define _branco_ 15 #define textcolor_2( letras, fundo) \ SetConsoleTextAttribute( \ GetStdHandle(STD_OUTPUT_HANDLE), \ (letras|(fundo<<4)) \ ) por exemplo usando isso: textcolor_2( _vermelho_claro_, _amarelo_ ); Acontece o esperado e passa a escrever em vermelho claro em fundo amarelo. Eis o gabarito de que falei. Pode usar os números direto nessa função depois de escolher no gabarito. Isso quer dizer que pode escrever em seu programa textcolor_2( 12,7); para usar vermelho em fundo cinza como está aí acima E como limpar a tela? Pois é. Quanto você começa a usar essas coisas de cursor para todo lado acaba sendo mais simples reescrever as coisas e então precisa limpar a tela toda hora. Limpar a tela é a mesma coisa que centralizar o texto. Você vai lá, vê o tamanho da tela e apaga tudo escrevendo espaços na tela inteira. Como o computador é mais rápido que os olhos... Você vai achar que apagou mesmo tudo. No windows você usa aquele comando CLS então faria sentido usar uma função com o mesmo nome. Veja uma: void 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; 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; }; // cls() É igualzinho ao caso de escrever no meio da tela: identifica a console preenche a estrutura com as informações vê o tamanho da tela e as cores em uso chama essas funções FillConsole_xyz aí de cima pra escrever espaços na tela toda e já era. Um programa de exemplo Vou mostrar um programa porque estive até procurando e não há um exemplo simples de como fazer algo assim. O programa faz o que já expliquei, mas para ficar mais óbvio tem uma função borda() que desenha uma borda na janela toda usando a letra que você escolher, e uma função mostra() que imprime uma única linha na posição central da tela. Rode isso em seu computador e volte a escrever para a gente saber se entendeu... main() int main(int argc, char** argv) { cls(); borda('*'); mostra("Bem no meio da tela"); }; // main() Sim, só isso. cls() limpa a tela borda('*') desenha um asterisco na borda da tela para a gente conferir se está certinho o tamanho mostra() escreve o texto bem no centro da tela, considerando o tamanho da tela no momento em que você chama a função O resultado Só isso.Eis o programa de teste #define _CRT_SECURE_NO_WARNINGS #define _preto_ 0 #define _azul_ 1 #define _verde_ 2 #define _ciano_ 3 #define _vermelho_ 4 #define _magenta_ 5 #define _marron_ 6 #define _cinza_claro_ 7 #define _cinza_escuro_ 8 #define _azul_claro_ 9 #define _verde_claro_ 10 #define _ciano_claro_ 11 #define _vermelho_claro_ 12 #define _magenta_claro_ 13 #define _amarelo_ 14 #define _branco_ 15 #define textcolor_2( letras, fundo) \ SetConsoleTextAttribute( \ GetStdHandle(STD_OUTPUT_HANDLE), \ (letras|(fundo<<4)) \ ) #include <stdio.h> #include <windows.h> void borda(char); void cls(); void gotoYX(int, int); void mostra(char); void text_color(int, int); int main(int argc, char** argv) { cls(); borda('*'); mostra("Bem no meio da tela"); }; // main() void borda(char c) { // desenha o caracter c em toda a borda da console // para testar os limites. Nao usa a ultima linha HANDLE H = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_SCREEN_BUFFER_INFO info; GetConsoleScreenBufferInfo(H, &info); int linhas = 1 - info.srWindow.Top + info.srWindow.Bottom; int colunas = 1 + info.srWindow.Right - info.srWindow.Left; printf("Buffer: %d linhas, %d colunas em Console Windows\n", info.dwSize.Y, info.dwSize.X); printf("Viewport: upper-left: (%d,%d) bottom-right: (%d,%d) = (%d,%d)\n", info.srWindow.Top, info.srWindow.Left, info.srWindow.Bottom, info.srWindow.Right, linhas, colunas ); char* barra = (char*)malloc(1 + sizeof(char) * colunas); memset(barra, c, colunas); *(colunas + barra) = 0; // termina a string cls(); gotoYX(0, 0); printf("%s\n", barra); for (int i = 1; i < linhas - 2; i++) { gotoYX(i, 0); printf("*"); gotoYX(i, colunas - 1); printf("*"); } gotoYX(linhas - 2, 0); printf("%s\n", barra); free((void*)barra); return; }; // borda() void 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; 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; }; // cls() void gotoYX(int linha, int coluna) { HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE); static COORD coord; coord.X = coluna; coord.Y = linha; SetConsoleCursorPosition(console, coord); return; }; // gotoYX() void mostra(char* texto) { HANDLE H = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_SCREEN_BUFFER_INFO info; GetConsoleScreenBufferInfo(H, &info); int linhas = info.srWindow.Bottom - info.srWindow.Top + 1; // altura da parede int colunas = info.srWindow.Right - info.srWindow.Left + 1; // largura da parede int largura = strlen(texto); int centroL = linhas / 2; // altura do quadro int centroC = colunas / 2 - largura; // distancia da margem da parede text_color(_branco_, _preto_); gotoYX(centroL, centroC); // posiciona printf("%s", texto); // mostra o texto char c = getc(stdin); return; }; // mostra() void text_color(int letras, int fundo) { SetConsoleTextAttribute( GetStdHandle(STD_OUTPUT_HANDLE), letras | (fundo << 4) ); } // text_color
-
Então, sobre essas coisas, @devair1010 @yuri_carneiro acho que seria o caso de recorrer a livros e revistas dessa época, ou a pessoas que programavam computadores na ocasião. Não era nada assim Pois é, havia e era mais comum do que é hoje. Hoje uma expressão virou de uso comum: "imprimir" virou mostrar algo na tela, e imprimir de fato desapareceu, como se as impressoras não existissem mais. Basta perguntar a algum "moderno programador" para que serve o caracter form-feed, ASCII 12 e vai ver a distância entre eles e os velhos tempos em que control-p imprimia o conteúdo da tela. NA IMPRESSORA. E o FF pula para a próxima página na impressora e então tinha que ter alguém atento --- se chamavam operadores na época e era uma profissão --- porque se um programa começasse a imprimir lixo na impressora e tivesse muitos desses FF uma caixa de papel ia parar do lado errado da impressora em um instantinho Nos anos 70 a saída de um programa de computador era quase que sempre a impressora. E claro que era muito importante alinhar texto, centralizar os relatórios e preparar as tabelas. A gente até comprava formulários --- sim, papel --- específicos para isso, na verdade. E as impressoras em geral imprimiam linhas de 132 colunas, e a maioria não tinha letras minúsculas. Outro tamanho comum era de 80 colunas e que passou a ser usado também quando começaram a surgir os terminais, já nos anos 80 eu diria. As páginas tinham sempre 66 linhas, em alguns casos 88. Veja por exemplo a impressora mãe de todas, a IBM 1403 Line Printer e vai ver do que estou falando. A folha de papel via de regra tinha 11 polegadas de altura e como se usavam 6 ou raramente 8 linhas por polegada aí está o número de linhas por página. E o papel era o formulário contínuo pre-picotado e de boa qualidade porque as impressoras eram muito rápidas e meio estúpidas na hora de puxar o papel. 600 a 1100 linhas por minuto era um número comum. E como o nome já diz elas imprimiam uma linha inteira de cada vez. Não era bem assim, e faz tempo que não é. Veja hoje o padrão: 120 colunas por 40 linhas, mas internamente 120 colunas e 9001 linhas. Sim 9001 linhas e você pode ir para trás e para frente no que está lá. Nessa história estão faltando uns 15 anos. Essas funções que vejo toda hora citadas aqui no forum --- e que eu não conhecia --- foram introduzidas numa biblioteca chamada conio que era fornecida com o compilador C da Borland, turbo C, e que começou a ser vendido em 1987, PARA MS-DOS. Na cola do Turbo Pascal que tinha saído uns dois anos antes com enorme sucesso. Comprei várias licenças desses. Computadores e sistemas operacionais e linguagens de programação nada tem a ver com Windows e DOS. Windows 1.0 saiu em 1985, e se programavam computadores já nos anos 50. Cursor e console são coisas dos anos 80 e os terminais tinham 24 linhas não 25. As referências históricas de terminais importantes foram mesmo a linha IBM-3278 e claro os DEC VT-52 VT-100 e VT-220 de onde vem todas as sequências de comando usadas hoje no Unix e derivados. Usei muito esses vou acabar ficando deprimido Não seria justo não lembrar que os terminais do Linux se chamam tty por causa dos terminais, TeleTYpe. E o DEC LA36 seria um exemplo perfeito, provavelmente um dos que Dennis Ritchie usou no DEC PDP-8 e depois PDP-11 que usou para desenvolver a linguagem C e o próprio Unix dos '70 em diante. Veja um aí com o formulário de 132 colunas. Usei muito esse. Ele treinava você a se sentar com cuidado para não pisar no papel e rasgar tudo e ficar todo mundo zoando você enquanto ajustava tudo de novo. gotoxy() e textcolor() Muitas vezes já escrevi e falei sobre isso, mesmo aqui neste forum: essas funções nada acrescentam e não são de fato o modelo de programação recomendado no Windows nos últimos 30 anos. E esse modelo está mudando como eu também já falei aqui. O "novo" terminal do Windows é muito melhor e usa outro modelo de programação, muito embora vá continuar aceitando esse modo antigo para todo o sempre por causa do imenso número de programas que foi criado em torno disso. Porque importa o novo terminal? Em especial porque ele é muito, muito mais rápido. Porque? Porque usa novas tecnologias, DirectX como nos games, e a janela da console é processada pela placa de vídeo --- GPU --- e não mais pelas funções do Windows. E trata Unicode nativamente para processar caracteres em qualquer idioma, muito além do super chato suporte aos caracteres acentuados que se tem hoje com as modestas code pages. Bem como emojis e coisas assim. E tabs. E é compatível com o modo de programação do Unix, de modo que os programas para console do Unix agora podem rodar no Windows. Diretamente. Foi escrito em C++ e o código fonte está disponível em https://github.com/microsoft/terminal. Sim, o código do Terminal do Windows é agora de domínio público. O código atual. E o WSL --- sistema que roda Linux no Windows --- também está disponível de graça para rodar no Windows. Na loja do Windows você pode baixar por exemplo Ubuntu 18 e SUSE 15 de graça. E entra em uns 5 segundos ou menos em um computador comum, sem mexer no Windows 10. Sem dual boot, sem máquina virtual, sem grub... Exemplo Veja o novo terminal no Windows 10 rodando aquele gabarito que eu postei outro dia com o programa que escrevi para mostrar as combinações de cores da console, mais uma aba com o Ubuntu 18 e outra com o SUSE Linux 15 e ,mais uma console... Documentação da programação da console em Windows https://docs.microsoft.com/en-us/windows/console/ Documentação sobre as mudanças no Terminal sempre está disponível a partir do link na própria tela do Windows. Veja nas propriedades do prompt de comando: Espero que ajude a ilustrar como eram os velhos tempos e como pode ser agora
-
Essa nomenclatura é mesmo folclórica. É muito comum a gente ler nos livros de referência explicação tentando a analogia com as bolhas subindo no líquido e depois ver aos autores descrevendo o algoritmo para classificar em ordem crescente e começando do primeiro, ou usando recursão a partir do penúltimo até reduzir o vetor a um elemento. Como descrito aqui. Mas então devia se chamar Anchor Sort, o sort da âncora, porque as bolhas como se sabe sobem. E o algoritmo geralmente publicado --- e até algumas animações que a gente vê por aí --- "desce" seguindo a lei da gravidade e afundando como uma âncora e não subindo como as bolhas. A implementação correspondente ao nome de bolha seria começar do fundo e comparar até o início de modo que o menor elemento fosse subindo como as tais bolhas afinal.
-
Em C esta é praticamente a definição de fscanf() e fprintf(). Em C++ use streams. Bem mais simples Veja esse exemplo que copia um arquivo em outro // Copy a file #include <fstream> // std::ifstream, std::ofstream int main () { std::ifstream infile ("test.txt",std::ifstream::binary); std::ofstream outfile ("new.txt",std::ofstream::binary); // get size of file infile.seekg (0,infile.end); long size = infile.tellg(); infile.seekg (0); // allocate memory for file content char* buffer = new char[size]; // read content of infile infile.read (buffer,size); // write to outfile outfile.write (buffer,size); // release dynamically-allocated memory delete[] buffer; outfile.close(); infile.close(); return 0; } Direto da fonte
-
foi mal... Escreva subtracao Acentos e cores nada acrescentam ao seu programa. Sempre escrevo isso então aí vai de novo... Funções são mais úteis quando mais genéricas. Receba os valores como parâmetro e retorne o resultado. Faça o simples. Exemplo float multiplica(float a, float b) { return a * b; } É bem mais esperto que int mult(){ resp = X*Y; textcolor_2(10,12); printf("\n Resulado da Multiplica%c%co de %.2f X %.2f -> %.2f \n\n", 135,198,X,Y,resp); } Que retorna um int e você nem retorna nada. E não imprima os valores dentro de uma função, pelo mesmo motivo: pra que uma função que usa variáveis externas X e Y só essas e imprime de um certo fixo modo? Não é para isso que as funções existem e não é para isso que esse exercício foi escrito. Se você usar a função que eu mostrei pode por exemplo escrever float total = multiplica(2,4) + multiplica(1,2); e total vai ficar com 10, como esperado. Direto no código. Se usar essa mult() que escreveu não vai a lugar algum... Mais ainda, imagine uma função assim float calculadora( int operadorA, char operador, int operandoB); E você poderia chamar assim float total = calculadora(1,'+', 3) + calculadora(2, '*', 8); por exemplo e ficaria bem mais genérico, certo?
-
C++ exercício em c++ . construir um programa para controlar as notas de 20 alunos
arfneto respondeu ao tópico de Bruno Seppe em C/C#/C++
E qual a sua dúvida afinal? Programe essas coisas em separado, se ainda não o fez... busca binária, gravação de arquivo, sort, busca binária, essas coisas. E poste algo objetivo -
Esse é um programa em C, não em C++ Não parece ter nada de especial, e parece nem estar pronto. Imagino que esta linha if (flag1=0) está erada e era para ser == o operador. Como termina esse troço? E esses flag2 flag3 seriam para que?
-
escrever em C é mais rápido e compacto mas pode ser bem mais difícil modelar uma solução sofisticada. Por outro lado em C++ você tem muito muito mais suporte da linguagem e das classes e da STL, a biblioteca gigante, com coisas como árvores, filas, conjuntos, pilhas, o diabo. Exceções definidas pelo usuário seria uma boa lembrança também. Mais opções de interface gráfica mais segurança de acesso e coisas assim. Sim, vai rodar mais devagar, mas nada perto de java ou Python. E você pode usar C e C++ sem stress no mesmo projeto. Em geral não é assim com outras linguagens. O Windows faz isso com Windows+shift+S há eras e já salva a imagem na área de transferência. Ou Windows+PrintScreen para copiar a tela inteira direto para a pasta Capturas de Tela no windows em português. E funciona muito bem. Mesmo para recortar áreas que estão em terminais separados, tipo um retângulo do centro de 3 telas numa máquina que tenha vários terminais. E seria o diabo programar algo assim. Como isso já faz parte do sistema você podia simular a sequência de teclas no seu programa e ficar com isso de graça. E depois usar a própria área de transferência para copiar o resultado para o seu programa. Também tem vários produtos, alguns grátis, que a gente usa para produzir material de treinamento por exemplo, e talvez pudesse ajudar a resolver seu problema ou inspirar sua solução. Camtasia Studio é sensacional e pode ser usado por um mês de graça TinyTake é bem legal e grátis Flashback Pro é pago mas pode ser usado por 30 dias de graça. Bem legal Sobre a performance na captura Em geral se usa algum tipo de gatilho -- alarme -- para saber se algo mudou na tela entre cada acionamento para aumentar a performance. E mecanismos de comparação entre as telas para copiar só o que mudou. Uma boa razão para escrever em C++ seria usar DirectX ou OpenGL para tratar o vídeo. São as bibliotecas usadas por exemplo para escrever jogos então a performance é máxima. Sobre C e C++ Uma boa maneira de aprender C++ é reescrever algo que escreveu ou conhece em C em C++. Minha opinião, claro. Alguma leitura sobre Objetos, Classes, Herança e Polimorfismo ajudaria pra caramba. C++ é uma linguagem enorme e muito muito poderosa. Se tiver um projeto desse tipo, talvez eu possa te ajudar.
-
Não exatamente. Escrevi muito rápido. Essas 6 colunas eram reservadas para o número do comando, que é opcional
-
Eu disse outro dia que não se justificava ter uma função como essa textcolor_2() e postei um #define para textcolor_2() com a ideia de mostrar que era meio besta existir tal função, mas parece que essa, como gotoxy() já entraram para a cultura popular, talvez pela idade e alcance dos antigos compiladores da Borland e o header conio afinal. Vi que trocou essa função por um #define --- dois na verdade --- em um programa que postou. E vou dar uns palpites a mais, e espero não parecer arrogante ou off-topic. Espero que não se importe Já escrevi isso outras vezes aqui: na console do Windows a cor é codificada em um único byte e é um bitmask. E em bitmask se usam operadores de bit, de modo que não se encontra na literatura algo como color = l+(f<<4)); por exemplo, como escreveu no #define. Pode ver isso em fontes do Windows, do Linux e milhões de códigos open source. Para configurar bitmasks se usa operadores de bit e o normal seria como postei color = letras|(fundo<<4); // em bitmasks, operadores bitwise Imagino que tenha escrito #define u GetStdHandle(STD_OUTPUT_HANDLE) #define textcolor_2(l,f) SetConsoleTextAttribute(u,l+(f<<4)); porque a linha ia ficar muito larga na tela. Note que os argumentos de um #define são expandidos ANTES da compilação então não precisa economizar e pode escrever algo mais legível, e que você pode continuar um macro --- #define --- por várias linhas, simplesmente usando um backslash "\" para indicar continuação, como em #define textcolor_2( letras, fundo) \ SetConsoleTextAttribute( \ GetStdHandle(STD_OUTPUT_HANDLE), \ (letras|(fundo<<4)) \ ) Talvez usar #define para as cores fosse prático também. algo como #define _preto_ 0 #define _azul_ 1 #define _verde_ 2 #define _ciano_ 3 #define _vermelho_ 4 #define _magenta_ 5 #define _marron_ 6 #define _cinza_claro_ 7 #define _cinza_escuro_ 8 #define _azul_claro_ 9 #define _verde_claro_ 10 #define _ciano_claro_ 11 #define _vermelho_claro_ 12 #define _magenta_claro_ 13 #define _amarelo_ 14 #define _branco_ 15 Usei um underline antes e depois da cor para evitar colisão com variáveis do programa e para indicar que é uma constante criada por #define. É uma técnica comum. Os compiladores já mudam em geral a cor na edição do programa, e os __ ajudam a separar as coisas e a diminuir a preocupação com colisão de nomes Isso substituiria o super chato enum com as cores. E você poderia escrever ao invés de textcolor_2(11,0); o mais legível textcolor_2( _ciano_claro_, _preto_ ); sem ter que declarar aquele enum E o bloco de definições ficaria #define _preto_ 0 #define _azul_ 1 #define _verde_ 2 #define _ciano_ 3 #define _vermelho_ 4 #define _magenta_ 5 #define _marron_ 6 #define _cinza_claro_ 7 #define _cinza_escuro_ 8 #define _azul_claro_ 9 #define _verde_claro_ 10 #define _ciano_claro_ 11 #define _vermelho_claro_ 12 #define _magenta_claro_ 13 #define _amarelo_ 14 #define _branco_ 15 #define textcolor_2( letras, fundo) \ SetConsoleTextAttribute( \ GetStdHandle(STD_OUTPUT_HANDLE), \ (letras|(fundo<<4)) \ ) :) Espero que ajude alguém
-
Seu professor não copiou direito. Faltam os números de comando e tem algumas coisas trocadas como apontado acima por @devair1010 A conversão em si é trivial. DIMENSION é o comando de alocação de memória para vetores. DO é a estrutura de loop. Os números que deveriam estar à esquerda são parte ativa do programa e se puder voltar até o programa original e copiar o que está faltando eliminaria a chance de algum chute errado. Os parenteses são usados para indicar os índices das matrizes. WRITE / FORMAT são associados mas está faltando mais uma vez o número do comando à esquerda. Você pode ver isso como um printf() onde a string de formato está no FORMAT. 6 é o número do arquivo, como em C se usa 0 1 e 2. 6 seria stdout. E 25 é o número do comando format associado ao write. Como só tem um FORMAT nesse caso ficou fácil Tudo em maiúsculas porque nos anos 60/70 não se usavam minúsculas nem terminais nem editores de texto velhos tempos que a gente usava cartões perfurados de 80 colunas com um cartão sendo uma linha de programa. 80 colunas e as 6 primeiras eram o número do comando, o que está faltando na sua listagem. A coluna 7 era indicadora de continuação e o programa parava na coluna 72 em geral. Da 73 a 80 eram reservadas para numeração. No fundo FORTRAN é bem simples. O próprio nome vem de FORmula TRANslator e já sugere a simplicidade que é pegar um algoritmo e escrever em FORTRAN. COBOL, a outra linguagem bem popular na época também é bem simples e muito legível. Ambas são ainda muito usadas hoje. Se usava em alguns lugares Algol, similar a Pascal, e claro Assembler que não mudou muito exceto pelo óbvio fato de que o conjunto de instruções hoje é absolutamente enorme em relação ao daquela época.
-
C Problema em colocar uma struct dentro de uma matriz ixj
arfneto respondeu ao tópico de robson s martins em C/C#/C++
Acho que está melhor seu código. Vou ver se entendo esse problema do nome a seguir. Não respondeu ao que te perguntei: você sabe escrever funções? E aquela necessidade de ter int linha e coluna na struct E aquilo de struct dentro de struct? Onde está o resto do enunciado onde está escrito isso? Não deve ler o nome do cliente antes de saber se a poltrona desejada está livre... Se a poltrona desejada já está ocupada apenas avise e volte para o menu para ele escolher outra Exemplo de struct mais perto da realidade struct cadeira { char nome[50]; int status; }; typedef struct cadeira Cadeira; struct teatro { char nome_da_sala[50]; Cadeira cadeiras[5][4]; }; typedef struct teatro Teatro; Qual a diferença afinal? Nesse modelo uma cadeira tem apenas um status e um nome de cliente. Todas cadeiras são iguais afinal. A posição física dela vai dar um número de fileira e um número de coluna E ao ser vendida passa a ter um cliente para uma certa sessão. Um teatro tem um nome e as poltronas e a posição delas na matriz cadeiras fornece a fileira e a poltrona, usando a nomenclatura mais comum nos teatros. E com esse modelo abstrato mais perto da realidade tudo fica mais fácil. Exemplo vamos imaginar um programa que inicie com as poltronas disponíveis claro, aí mostramos as disponíveis, marcamos umas como ocupadas e mostramos as disponíveis e as ocupadas. Usar nomes e estrutura mais próximos da realidade também facilita ler o programa. Veja a seguir. Marcar as poltronas como livres fica simples for (int fileira = 0; fileira < 5; fileira += 1) { for (int coluna = 0; coluna < 4; coluna += 1) { sala.cadeiras[fileira][coluna].nome[0] = 0; // sem nome sala.cadeiras[fileira][coluna].status = 0; // disponivel } // for } // for Mostrar as poltronas livres também printf("\nMostra poltronas LIVRES\n\n"); n = 0; for (int fileira = 0; fileira < 5; fileira += 1) { char f = 'A' + fileira; // pra facilitar printf("Fileira %c: ", f ); for (int coluna = 0; coluna < 4; coluna += 1) { if (sala.cadeiras[fileira][coluna].status == 0) { printf("%c%d ", f, coluna + 1); n = n + 1; } } // for printf("\n"); } // for printf("\n%d poltronas livres\n\n", n); "Vendendo" as das diagonais para clientes com nomes diferentes para poder ver na listagem sala.cadeiras[0][0].status = 1; strcpy(sala.cadeiras[0][0].nome, "Cliente na Poltrona A1"); sala.cadeiras[1][1].status = 1; strcpy(sala.cadeiras[1][1].nome, "Cliente na Poltrona B2"); sala.cadeiras[2][2].status = 1; strcpy(sala.cadeiras[2][2].nome, "Cliente na Poltrona C3"); sala.cadeiras[3][3].status = 1; strcpy(sala.cadeiras[3][3].nome, "Cliente na Poltrona D4"); sala.cadeiras[4][0].status = 1; strcpy(sala.cadeiras[4][0].nome, "Cliente na Poltrona E1"); printf("\nMarcadas como ocupadas A1 B2 C3 D4 E1\n\n"); Mostrar as poltronas ocupadas é quase igual printf("\nMostra poltronas OCUPADAS\n\n"); n = 0; for (int fileira = 0; fileira < 5; fileira += 1) { char f = 'A' + fileira; // pra facilitar printf("Fileira %c:\n", f); for (int coluna = 0; coluna < 4; coluna += 1) { if (sala.cadeiras[fileira][coluna].status == 1) { printf(" %c%d %s\n", f, coluna + 1, // poltrona sala.cadeiras[fileira][coluna].nome // nome ); n = n + 1; } } // for } // for printf("\n%d poltronas ocupadas\n", n); Um programa usando esse código e essas estruturas mostraria Mostra poltronas LIVRES Fileira A: A1 A2 A3 A4 Fileira B: B1 B2 B3 B4 Fileira C: C1 C2 C3 C4 Fileira D: D1 D2 D3 D4 Fileira E: E1 E2 E3 E4 20 poltronas livres Marcadas como ocupadas A1 B2 C3 D4 E1 Mostra poltronas LIVRES Fileira A: A2 A3 A4 Fileira B: B1 B3 B4 Fileira C: C1 C2 C4 Fileira D: D1 D2 D3 Fileira E: E2 E3 E4 15 poltronas livres Mostra poltronas OCUPADAS Fileira A: A1 Cliente na Poltrona A1 Fileira B: B2 Cliente na Poltrona B2 Fileira C: C3 Cliente na Poltrona C3 Fileira D: D4 Cliente na Poltrona D4 Fileira E: E1 Cliente na Poltrona E1 5 poltronas ocupadas Eis o programa todo #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <windows.h> struct cadeira { char nome[50]; int status; }; typedef struct cadeira Cadeira; struct teatro { char nome_da_sala[50]; Cadeira cadeiras[5][4]; }; typedef struct teatro Teatro; int main(int argc, char** argv) { Teatro sala; int n; // prepara tudo: todas livres for (int fileira = 0; fileira < 5; fileira += 1) { for (int coluna = 0; coluna < 4; coluna += 1) { sala.cadeiras[fileira][coluna].nome[0] = 0; // sem nome sala.cadeiras[fileira][coluna].status = 0; // disponivel } // for } // for // mostra as livres printf("\nMostra poltronas LIVRES\n\n"); n = 0; for (int fileira = 0; fileira < 5; fileira += 1) { char f = 'A' + fileira; // pra facilitar printf("Fileira %c: ", f ); for (int coluna = 0; coluna < 4; coluna += 1) { if (sala.cadeiras[fileira][coluna].status == 0) { printf("%c%d ", f, coluna + 1); n = n + 1; } } // for printf("\n"); } // for printf("\n%d poltronas livres\n\n", n); // marca algumas como ocupadas sala.cadeiras[0][0].status = 1; strcpy(sala.cadeiras[0][0].nome, "Cliente na Poltrona A1"); sala.cadeiras[1][1].status = 1; strcpy(sala.cadeiras[1][1].nome, "Cliente na Poltrona B2"); sala.cadeiras[2][2].status = 1; strcpy(sala.cadeiras[2][2].nome, "Cliente na Poltrona C3"); sala.cadeiras[3][3].status = 1; strcpy(sala.cadeiras[3][3].nome, "Cliente na Poltrona D4"); sala.cadeiras[4][0].status = 1; strcpy(sala.cadeiras[4][0].nome, "Cliente na Poltrona E1"); printf("\nMarcadas como ocupadas A1 B2 C3 D4 E1\n\n"); // mostra as livres de novo printf("\nMostra poltronas LIVRES\n\n"); n = 0; for (int fileira = 0; fileira < 5; fileira += 1) { char f = 'A' + fileira; // pra facilitar printf("Fileira %c: ", f); for (int coluna = 0; coluna < 4; coluna += 1) { if (sala.cadeiras[fileira][coluna].status == 0) { printf("%c%d ", f, coluna + 1); n = n + 1; } } // for printf("\n"); } // for printf("%d poltronas livres\n", n); // agora mostra as ocupadas printf("\nMostra poltronas OCUPADAS\n\n"); n = 0; for (int fileira = 0; fileira < 5; fileira += 1) { char f = 'A' + fileira; // pra facilitar printf("Fileira %c:\n", f); for (int coluna = 0; coluna < 4; coluna += 1) { if (sala.cadeiras[fileira][coluna].status == 1) { printf(" %c%d %s\n", f, coluna + 1, // poltrona sala.cadeiras[fileira][coluna].nome // nome ); n = n + 1; } } // for } // for printf("\n%d poltronas ocupadas\n", n); return 0; } Vi que mudou o tamanho do nome de 50 para 10. Mas pensando no inicial de 50 podia usar algo assim para o status 0 1 2 3 4 5 6 7 0 * 0 * 0 * 0 * 0 * 0 * 0 * **************************** * Cadeira: A 1 * * Situação: OCUPADA * * 012345678901234567890 * * 012345678901234567890 * * 01234567890 * **************************** **************************** * Cadeira: A 1 * * Situação: LIVRE * * * * * * * **************************** Claro que as primeiras linhas são só uma régua para numerar as colunas Isso deve ajudar a ver como endereçar as estruturas e entender como linha e coluna são implícitas no modelo -
C Problema em colocar uma struct dentro de uma matriz ixj
arfneto respondeu ao tópico de robson s martins em C/C#/C++
Vou dar uma olhada de novo logo mais. Essa estrutura para representar o teatro não está boa e está jogando contra. Não entendi onde está isso no enunciado. Você tem mais do enunciado que não postou? O problema na representação Quanto mais perto sua estrutura de dados estiver da realidade vai ficar mais fácil para programar a solução. Se uma estrutura Teatro tem um nome deveria ser o nome da Sala e não do cliente que comprou um ticket para uma cadeira. O nome e o status na estrutura teatro se referem a cadeiras. Pense bem. struct cadeiras{ int linha; int coluna; }; struct teatro{ char nome[50]; int status; struct cadeiras c; }; struct teatro t[4][5]; Mais perto da realidade seria struct cadeira { int coluna; int linha; char nome[50]; int status; }; typedef struct cadeira Cadeira; struct teatro { char nome_da_sala[50]; Cadeira cadeiras[4][5]; }; typedef struct teatro Teatro; Você sabe escrever funções? São só blocos de código com um nome e uns detalhes, mas facilitam muito sia vida -
C Problema em colocar uma struct dentro de uma matriz ixj
arfneto respondeu ao tópico de robson s martins em C/C#/C++
Nada muda. Apenas coloque esse desenho da struct dentro daquele gabarito ao invés de usar só A1 .. E4 Faça um desenho com o bloco de notas usando isso e programa assim com as linhas e colunas. Se precisar de ajuda posso mostrar um gabarito pra voce logo mais -
Herbert, isso funciona ao contrário: na nomenclatura mais usual, o click do mouse gera um evento e o sistema é avisado sobre a posição (x,y) do mouse no momento do click e mais algumas coisas tipo qual botão do mouse foi usado, alguma tecla tipo shift, control ou alt pressionada e tal. O programa que recebe essa mensagem tem controle sobre a tela, a janela toda, e avisa todo mundo sobre o click. tipo a região em que está em outra cor, que seria um botão, a região mais ampla que seria a janela. e assim por diante... Sendo bem repetitivo, não há razão pra fazer isso porque por definição é a interface gráfica, seja em Windows, seja na Web seja em Linux, seja nos telefones. Então você usa a interface e pronto. Grandes programadores criaram essas coisas, então é melhor usar do que reescrever
-
C Problema em colocar uma struct dentro de uma matriz ixj
arfneto respondeu ao tópico de robson s martins em C/C#/C++
Não entendi o que tem a ver os ponteiros com a estrutura. Como o tamanho já foi definido e é pequeno, porque não usar cadeira Cadeira[5][4]; e escrever com te expliquei, usando Letra e Número para identificar as poltronas e usando aquele texto que te mostrei como gabarito? adicionado 20 minutos depois São 5 filas de 4 poltronas então as fileiras começam em A e tem 4 cadeiras, e correspondem à linha da matriz. As colunas são 4 e você pode derivar os números direto,e pode usar maiusculas para as poltronas ocupadas, ou colocar parenteses em volta, ou mesmo mudar a cor, usando o gabarito que te mostrei. Postei um programa hoje mesmo aqui que faz esse lance de mudar a cor por exemplo. Veja no tópico "problemas o full screen" Se for usar maiúsculas para as poltronas ocupadas por exemplo, lembro que a diferença entre uma letra maiúscula e a minúscula correspondente é sempre 32 então mostrar o status fica bem fácil varre a matriz e para as poltronas ocupadas você subtrai 32 do valor... -
textcolor_2 Já tinha visto esse código aqui no forum antes, e na verdade eu não conhecia. Entendi que é uma herença dos compiladores da Borland do início dos anos 80 e fazia parte de uma biblioteca chamada conio ao que parece. Mas não entendo porque ainda é usada e muito menos porque foi escrita assim. Qual a razão para os static int __BACKGROUND e __FOREGROUND "globais" e estáticos que não são usados, já que os valores são imediatamente redefinidos porque não passar o Handle da console como argumento já que é sempre o mesmo para o programa todo? porque misturar operadores aritméticos e de bit no mesmo comando, sendo que a cor é um bitmask por definição? textcolor_2 podia ser um simples #define e não uma função #define textcolor_2( letras, fundo) SetConsoleTextAttribute( GetStdHandle(STD_OUTPUT_HANDLE), (letras|(fundo<<4)) ) e você poderia escrever printf("\nteste antes de mudar a cor\n"); textcolor_2 (amarelo, preto); printf("Amarelo sobre preto\n"); text_color(H, 15, 0); /* preto sobre branco */ printf("\nteste depois de mudar a cor\n"); Usando os códigos corretos. E o texto seria escrito em amarelo sobre preto, claro As 16 cores, em português typedef enum { preto, // 0 azul, // 1 verde, // 2 ciano, // 3 vermelho, // 4 magenta, // 5 marron, // 6 cinza_claro, // 7 cinza_escuro, // 8 azul_claro, // 9 verde_claro, // 10 ciano_claro, // 11 vermelho_claro, // 12 magenta_claro, // 13 amarelo, // 14 branco // 15 } colors; Em consoleapi2.h, como eu disse, estão as constantes de cor. É o que se chama de bitmask, máscara de bits, e é um byte, um valor entre 0 e 255 que cobre ao mesmo tempo a cor de fundo e a cor da letra. E isso é autoritativo, então claro que essa textcolor_2 bem como a anterior se existiu usa os mesmos números. 1, 2 e 4 para azul, verde e vermelho, 8 para usar um tom mais intenso. E a mesma coisa acontece com as cores de fundo, só que deslocadas 4 bits para a esquerda para poder definir ao mesmo tempo. Assim a letra em verde vale 2 e o fundo em verde vale 32 por exemplo. Eis de novo as constantes do Windows #define FOREGROUND_BLUE 0x0001 // text color contains blue. #define FOREGROUND_GREEN 0x0002 // text color contains green. #define FOREGROUND_RED 0x0004 // text color contains red. #define FOREGROUND_INTENSITY 0x0008 // text color is intensified. #define BACKGROUND_BLUE 0x0010 // background color contains blue. #define BACKGROUND_GREEN 0x0020 // background color contains green. #define BACKGROUND_RED 0x0040 // background color contains red. #define BACKGROUND_INTENSITY 0x0080 // background color is intensified. Porque isso? Simples: para salvar uma configuração de cor azul intenso sobre vermelho normal você pode usar cor = FOREGROUND_BLUE | FOREGROUND_INTENSITY | BACKGROUND_RED; ou mesmo SetConsoleTextAttribute( GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE | FOREGROUND_INTENSITY | BACKGROUND_RED ); O amarelo por exemplo é o verde combinado com o vermelho no tom intenso então não por acaso o amarelo vale 14: 8 + 4 + 2 e você poderia escrever amarelo = FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY; Note que não se usa soma para essas coisas: trata-se de uma máscara de bits e a tradição é usar os operadores de bits... Um gabarito para Windows Existem milhões desses mas porque não escrever mais um? Eis o código for (int letra = 0; letra < 16; letra += 1) { for (int fundo = 0; fundo < 16; fundo += 1) { text_color(H, letra, fundo); printf(" %2d %2d ", letra, fundo); text_color(H, 15, 0); /* para delimitar os blocos */ printf(" "); } printf("\n"); } Eis o resultado Assim fica fácil ver: a cor de fundo é o número da direita, a cor das letras o número da esquerda em cada coluna. 16 linhas, 16 colunas e temos as possíveis combinações. Nada original. O texto inicial foi escrito em (5,10) para ter um exemplo de como posicionar o cursor no Windows. Eis o programa todo, que inclui uma textcolor_2 como macro --- #define --- e um teste do enun com as cores em português e mostra o gabarito em si. #define _CRT_SECURE_NO_WARNINGS #define textcolor_2( letras, fundo) SetConsoleTextAttribute( GetStdHandle(STD_OUTPUT_HANDLE), (letras|(fundo<<4)) ) #include <stdio.h> #include <windows.h> void text_color(HANDLE, int, int); int main(int argc, char** argv) { typedef enum { preto, // 0 azul, // 1 verde, // 2 ciano, // 3 vermelho, // 4 magenta, // 5 marron, // 6 cinza_claro, // 7 cinza_escuro, // 8 azul_claro, // 9 verde_claro, // 10 ciano_claro, // 11 vermelho_claro, // 12 magenta_claro, // 13 amarelo, // 14 branco // 15 } colors; HANDLE H = GetStdHandle(STD_OUTPUT_HANDLE); text_color(H, 15, 0 ); /* preto sobre branco */ COORD coord; coord.X = 5; coord.Y = 10; SetConsoleCursorPosition(H, coord); text_color(H, 15, 0); /* preto sobre branco */ printf("Gabarito (Frente|Fundo) escrito em (5,10) \n\n\n"); for (int letra = 0; letra < 16; letra += 1) { for (int fundo = 0; fundo < 16; fundo += 1) { text_color(H, letra, fundo); printf(" %2d %2d ", letra, fundo); text_color(H, 15, 0); /* para delimitar os blocos */ printf(" "); } text_color(H, 15, 0); /* para delimitar os blocos */ printf("\n"); } printf("\nteste antes de mudar a cor\n"); textcolor_2 (amarelo, preto); printf("Amarelo sobre preto\n"); text_color(H, 15, 0); /* preto sobre branco */ printf("\nteste depois de mudar a cor\n"); } void text_color(HANDLE Console, int letras, int fundo) { SetConsoleTextAttribute(Console, letras | (fundo<<4)); } Espero que os exemplos ajudem
-
Olá! Agora tenho um computador Como eu disse esse tema é um inferno para programar e pouco útil ou extremamente útil. Pouco útil se você está usando um computador comum que tem interface gráfica. Extremamente útil no outro caso. Por várias razões -- e não vou deixar tanto o tópico -- esse tema tem crescido de importância nos últimos anos, e uma montanha de dinheiro e grupos de pessoas competentes passaram a trabalhar nisso e o progresso já foi enorme desde a edição de aniversário do Windows 10. O Windows sempre teve um conjunto de funções para acessar a console e a documentação é enorme, claro. Eis o endereço oficial https://docs.microsoft.com/en-us/windows/console/console-reference onde tem tudo. No Unix não tinha nada disso porque a interface gráfica não fazia e não faz parte do sistema. O que se tem e tinha é feito via emulação de terminal. OK, antes eram os terminais mesmo, e os mais populares eram os da marca Digital, modelo VT-100 ou VT-52 e não por acaso nos manuais deles estão todas as sequências de programação da console para o Linux/Unix/MacOS. Como eu disse antes curses foi a primeira biblioteca de grande sucesso para criar interfaces gráficas no modo texto e depois evoluiu nara ncurses que pode usar hoje ainda. Com a interface gráfica veio o X-Windows e um mundo de opções. Convergência no Windows 10 Nos últimos anos foi criado o conceito de Terminal Virtual no Windows e é até onde eu vejo simplesmente fazer o Windows processar esses comandos do terminal do Linux, que são os comandos dos terminais da digital dos tempos antigos. Na documentação você vai ver que se chamar em C BOOL WINAPI SetConsoleMode( _In_ HANDLE hConsoleHandle, _In_ DWORD dwMode ); Documentada em https://docs.microsoft.com/en-us/windows/console/setconsolemode pode habilitar esse troço de Virtual Terminal E nunca funcionou direito, porque simplesmente não emulava todos os comandos e variava de versão para versão de Windows... Mas está sempre evoluindo Mas você pode habilitar isso e usar os mesmos comandos do Linux que usa os mesmos do Unix que usa os mesmos do terminal da Digital. O novo Terminal do Windows Um resultado desse projeto é o novo Terminal do Windows que você pode instalar a partir claro da loja do Windows. Saiu uma nova versão nessa terça 26 e rodar seu programa nesse novo terminal que é bem mais compatível e permite usar os comandos todos que vê nos programas por aí, como em ncurses Veja que também tem Ubuntu Suse e Fedora Linux na loja do windows, de graça e roda sem instalar nada mais, apenas o suporte do Windows. Mundo estranho esse A imagem abaixo é da loja do Windows, direto O desenvolvimento dessas coisas pode ser acompanhado no blog do próprio grupo da Microsoft que está escrevendo isso e o endereço é https://devblogs.microsoft.com/commandline/ Como é -- era -- no Windows: um exemplo comum Essa função mostra uns dados na tela a partir de uma posição linha/coluna e foi escrita como parte de um exemplo em C++ mas em C funciona igualzinho. Talvez ajude você a entender o mecanismo. Pode usar assim e seu programa vai funcionar. int Cartela::mostraXY(short X, short Y, short* cor) { // mostra a cartela a partir da posição (x,y) na tela // em principio igual a anterior mostra(), apenas posiciona o // cursor antes de imprimir cada linha // usa as cores como marcadas no vetor 'cor' int i; HANDLE H = GetStdHandle(STD_OUTPUT_HANDLE); COORD coord; coord.X = X; coord.Y = Y; SetConsoleCursorPosition(H, coord); SetConsoleTextAttribute(H, cor[0]); cout << "'" << nome << "' [" << setfill('0') << setw(3) << hits << "]"; coord.X = X; coord.Y++; SetConsoleCursorPosition(H, coord); // mostra valores[] for (i=0; i<tamanho; i++) { SetConsoleTextAttribute (H, cor[valores[i]]); cout << setfill('0') << setw(2) << valores[i] << " "; SetConsoleTextAttribute(H, cor[0]); if (i % 5 == 4) { coord.X = X; coord.Y++; SetConsoleCursorPosition(H, coord); } // end if } // end for coord.X = X; coord.Y++; SetConsoleCursorPosition(H, coord); return 0; } // end mostraXY() X e Y são as coordenadas e cor e o endereço de um vetor de cores que a lógica do programa preencheu com as cores certas. Acho que era algo como preto para os números que ainda não saíram e verde para os já sorteados. Era um bingo afinal. Posso te enviar o executável ou o programa inteiro, mas foi escrito em C++. Acho que se tirar o Cartela:: já compila em sua máquina e pode rodar em C Mas a lógica é a mesma e as funções também em Veja que no início você obtem o handle para a console, porque pode ter várias consoles, e salva em H porque vai usar toda hora. Preenche a estrutura COORD com o óbvio X e Y e depois usa as funções para salvar as cores e fontes em uso para poder restaurar ao final e aí imprime os dados e restaura ao sair. Cores no Windows em consoleapi.h Note que você só precisa incluir isso em seu programa ou talvez nem precise. E veja que você pode combinar as cores e atributo usando | o operador ou em C // // Attributes flags: // #define FOREGROUND_BLUE 0x0001 // text color contains blue. #define FOREGROUND_GREEN 0x0002 // text color contains green. #define FOREGROUND_RED 0x0004 // text color contains red. #define FOREGROUND_INTENSITY 0x0008 // text color is intensified. #define BACKGROUND_BLUE 0x0010 // background color contains blue. #define BACKGROUND_GREEN 0x0020 // background color contains green. #define BACKGROUND_RED 0x0040 // background color contains red. #define BACKGROUND_INTENSITY 0x0080 // background color is intensified. #define COMMON_LVB_LEADING_BYTE 0x0100 // Leading Byte of DBCS #define COMMON_LVB_TRAILING_BYTE 0x0200 // Trailing Byte of DBCS #define COMMON_LVB_GRID_HORIZONTAL 0x0400 // DBCS: Grid attribute: top horizontal. #define COMMON_LVB_GRID_LVERTICAL 0x0800 // DBCS: Grid attribute: left vertical. #define COMMON_LVB_GRID_RVERTICAL 0x1000 // DBCS: Grid attribute: right vertical. #define COMMON_LVB_REVERSE_VIDEO 0x4000 // DBCS: Reverse fore/back ground attribute. #define COMMON_LVB_UNDERSCORE 0x8000 // DBCS: Underscore. No Linux Aí não tem nada disso porque não existe essa tal console. No entanto quando você vai escrever num terminal o sistema interpreta esses caracteres de controle que um dia foram do VT-100 e por isso não existem funções. Claro que ao final ou você vai escrever ou vai usar algumas que alguém escreveu porque é um porre inserir isso nos comandos... Exemplo: se você enviar ESCAPE [ 33 m Algo para um terminal no Linux vai sair 'Algo' escrito em amarelo. E de modo similar você muda o cursor de posição, escreve em reverso, sublinhado, negrito, limpa a tela e outras funções mais exóticas. Direto de https://en.wikipedia.org/wiki/VT100 Usei muito esse terminal e o VT52 Espero que ajude a ter uma referência de como a console chegou onde está hoje. Vou repetir o que já disse antes: se tiver opção fuja disso e use algo como GTK que é bem moderno e funciona em C, ou use algo como C# e a interface do Windows, bem mais elegante e fácil. E se precisa de portabilidade e modo texto e C recomendo GTK ou o Windows Terminal novo e ncurses. adicionado 12 minutos depois Bem... na verdade não. o certo é você escrever HANDLE H = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_SCREEN_BUFFER_INFO info; GetConsoleScreenBufferInfo(H, &info); E aí o sistema faz a gentileza de preencher info com os dados corretos. typedef struct _CONSOLE_SCREEN_BUFFER_INFO { COORD dwSize; COORD dwCursorPosition; WORD wAttributes; SMALL_RECT srWindow; COORD dwMaximumWindowSize; } CONSOLE_SCREEN_BUFFER_INFO, *PCONSOLE_SCREEN_BUFFER_INFO; Como dá pra ver lá está dwSize do tipo COORD já conhecido typedef struct _COORD { SHORT X; SHORT Y; } COORD, *PCOORD; E lá estão as informações do tamanho da console no momento. Ela pode mudar a toda hora ou ser fixada com outro tamanho nas propriedades.... E aí você faz as contas para posicionar o texto, usando info->dwSize.X e info->dwSize.Y
-
Gitoxy() sequer é uma função de verdade. As coordenadas estão em uma estrutura coord postada logo acima acho que num código que@devair1010 postou e as cores estão em um cabeçalho, um header, um. H que acho que até se chama color no windows. No linux see pode usar as cores do terminal, direto do manual do terminal por exemplo
-
Yuri, a cada vez que vai escrever na tela você chama a função pra comparar o tamanho da tela porque pode ter que redesenhar tudo . E você calcula o tamanho o do que você vai escrever e faz as contas para identificar a coordenada certa. Só isso. adicionado 0 minutos depois Você é que faz as contas toda vez
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