Ir ao conteúdo

arfneto

Membro Pleno
  • Posts

    6.526
  • Cadastrado em

  • Última visita

Tudo que arfneto postou

  1. Acho que não entendeu. Ou eu não entendi Você não quer 90.000 arquivos de coordenadas. Você quer UM arquivo com 90.000 coordenadas. Entendeu o que eu expliquei sobre a declaração? Não é corrupção. Apenas é o que está lá. Aqueles sinais se referentes a coisas que não era para serem mostradas. Você está gravando algo para você mesmo ler, então pode definir o formato como for mais prático. E econômico. Sempre pode usar texto, mas se não vai editar não precisa disso. Você quer gravar 90.000 coordenadas e ler uma a uma? quer gravar um bloco delas e ler aos poucos? quer gravar um vetor com um certo número delas e carregar tudo de novo? Me explique o que quer e eu te ajudo a escrever. Que significa? Talvez "definitivamente" seja uma escolha exagerada de expressão
  2. O que está tentando fazer? Não entendi. Recomendo sempre, em especial para quem está começando e ainda não tem vícios, declarar as variáveis SEPARADAS do tipo. Esse aí é um exemplo do problema: As declarações em C++ são lidas da direta para esquerda. [90000] indica que está declarando 90.000 de algo. Um array. Um vetor. coordpers é o que está declarando FILE* é o tipo. ENTENDA: FILE*. você declara uma variável. coordpers é a variável. Está declarando 90.000 arquivos. Não 90000 coordenadas para algo. O mais claro: FILE* coordpers [90'000]; você pode usar as pas como separador de dígitos em C++ coordpers é FILE*, um ponteiro para arquivo, um Handle na terminologia do Windows. são 90 mil deles Não entendi o exemplo seguinte
  3. Assim vai dar mais trabalho. Faça o simples como eu disse. Se não vai usar outras linguagens ou compiladores ou Linux ou WSL ou Node ou algo assim, VS Code é mais problema que solução.
  4. @Daniel Bittencourt Não acho mesmo que valha a pena programar nesse mecanismo. Não se usa isso há épocas e por uma razão simples: os modelos de programação mais novos são mais produtivos e mais simples. Inclusive os da Microsoft. De todo todo, se quer usar isso a fonte de documentação e exemplos é a mesma. A dos donos do campo, da bola e das camisas. A Microsoft Veja a documentação a partir daqui: https://docs.microsoft.com/en-us/windows/win32/gdi/windows-gdi Exemplos Um número importante de exemplos está aqui: https://github.com/microsoft/Windows-classic-samples e acho que não tem nada parecido. Recomendo que instale Visual Studio em sua máquina. Se ficar lento apenas aumente sua paciência. Se não conseguir e puder gastar algum dinheiro e tempo, aumente então a memória de sua máquina, a versão de Windows e tente quem sabe um SSD. Mas não é imprescindível. O que tem nos tais exemplos? Tem de tudo. São centenas de projetos completos que você pode rodar com esse roteiro complicado: clique na solução, o arquivo sln, e clique no triângulo verde... Veja um pedaço: Tem uma parte só com exemplos de Windows7. Dentro dessa uma pasta com exemplos para iniciantes. Dentro dessas por exemplo uma pasta com exemplos de Win32... Veja lá. E você pode ler os programas todos e alguma documentação direto no GitHub. E pode baixar apenas o programa para rodar em seu ambiente Dev-C++, se fizer questão. Não é o melhor caminho, mas funciona. Para o VisualStudio é um passeio porque já está tudo arrumadinho, os includes, o ambiente, os projetos e tal. Você pode escolher o projeto na barra lateral --- Solution Explorer --- clicar no arquivo da solução, o .sln, e os arquivos todos já ficam disponíveis no IDE e pode rodar o exemplo... E rodar direto Com ou sem o debugger. Com o debugger é legal porque pode parar o programa nas chamadas a API e ver o que tem nas estruturas por exemplo. E eventualmente alterar em tempo real.
  5. não conheço o famoso id returned 1 exit status chamou GetLastError() ao menos? FormatMessage()? Com conseguiu o handle pra chamar setpixel? Está certo de que era válido? Dependendo da tela talvez possa improvisar algo com os blocos de desenho da codepage 437, ou mesmo números de 0 a 100 A API do windows é uma biblioteca também. Não usar uma biblioteca (de terceiros) pode ser só prejuízo. Não acho que tenha muita razão para não usar uma API dessas, tipo Qt, Opengl, DirectX, SDL ou GTK+ hoje em dia. É mais fácil e produtivo. E elas nem são muito diferentes. adicionado 1 minuto depois Não pegue. escreva um pequeno programa e teste você mesmo. Essas coisas não dão erro. SetPixel()
  6. Talvez só com uma tabela de referência... Mais curto, sem funções e direto com os bits #include <stdio.h> int main(void) { int n[3], res = 0; char ref[6][3] = { { 0,1,2 }, { 0,2,1 }, { 1,0,2 }, { 1,2,0 }, { 2,0,1 }, { 2,1,0 } }; do { printf("Entre com os 3 numeros, separados por ',': "); res = scanf("%d,%d,%d", &n[0], &n[1], &n[2]); } while (res != 3); if (n[0] < n[1]) // A<B { if (n[2] < n[0]) res = 4; // C<A<B else if (n[2] < n[1]) res = 1; else res = 0; } else // B<=A if (n[2] < n[1]) res = 5; // C<B<A else if (n[2] < n[0]) res = 3; else res = 2; printf( "Valores em ordem: entrada [%d,%d,%d] crescente [%d,%d,%d]" " decrescente [%d,%d,%d]\n", n[0], n[1], n[2], n[ref[res][0]], n[ref[res][1]], n[ref[res][2]], n[ref[res][2]], n[ref[res][1]], n[ref[res][0]]); return 0; }; Entre com os 3 numeros, separados por ',': 1,2,3 Valores em ordem: entrada [1,2,3] crescente [1,2,3] decrescente [3,2,1] Entre com os 3 numeros, separados por ',': 3,2,1 Valores em ordem: entrada [3,2,1] crescente [1,2,3] decrescente [3,2,1] Entre com os 3 numeros, separados por ',': 3,4,4 Valores em ordem: entrada [3,4,4] crescente [3,4,4] decrescente [4,4,3] adicionado 16 minutos depois Considere que se quer algo eficiente nesse contexto não pode considerar chamar funções. Só o tempo de preparar os argumentos e empilhar tudo e depois restaurar no retorno vai gastar umas 50 vezes mais de tempo
  7. Um exemplo para usar uma matriz de totais ou uma segunda dimensão na matriz original A lógica que estão usando pode ser vista assim: Exemplo 1 você tem uma matriz M[2][3] assim: a b c d e f e então cria uma matriz T[2][3] assim: 1 1 1 1 1 1 com os totais de ocorrências das letras. Exemplo 2 a a a a a b os totais seriam 5 0 0 0 0 1 Exemplo 3 a a b b X X 3 3 Os totais seriam 2 0 2 0 2 0 2 0 Acho que é o que fizeram, exceto que deixaram para ler tudo de novo depois, o que não é necessário nem eficiente. Na matriz de totais um valor zero na posição de uma letra indica que ela já tinha aparecido antes. Uma letra que apareça 3 vezes tem o valor 3 na posição correspondente à primeira ocorrência e zero nas outras duas. Uma propriedade interessante disso é que a soma de todos os valores dessa tabela deve bater com o total de elementos da matriz, linhas x colunas e você pode usar isso para testar. Uma outra é que por definição vai usar todos os valores da matriz, então NÃO precisa inicializar a matriz de totais. Exemplo: Usando matriz [ ] [ ] para ler os valores e totais [ ] [ ] para os totais e c para a letra... c = getchar(); papel->matriz[i][j] = c; // na matriz papel->total[i][j] = 0; // repetida n_lidos += 1; int x = 0; int y = 0; int nova_letra = 1; // assume nova letra for (int v = 0; v < n_lidos-1; v += 1) { // compara com os que ja leu if (c == papel->matriz[x][y]) { // entao ja tinha papel->total[x][y] += 1; nova_letra = 0; break; }; // if() y = y + 1; if (y >= papel->colunas) { y = 0; x = x + 1; }; // aponta para o prox na matriz }; // for(v) if (nova_letra) { papel->n_simbolos += 1; papel->total[i][j] = 1;// nova }; // if() while ((c = getchar()) != '\n' && c != EOF) {}; Esse código faz o ajuste dos totais a cada leitura. Apenas um loop olhando para trás nas letras que já foram lidas e acertando os contadores. Ao final da leitura os n_simbolos estão totalizados na matriz e se pode mostrar, sem ter que varrer a matriz a toa de novo. Se vê problemas em usar uma estrutura basta apagar as referências a ela e declarar as variáveis localmente Uma função que lê a matriz e faz as contas ao mesmo tempo: E como mostrar os totais? Ao final n_simbolos distintos estarão na matriz totais[ ] [ ]. Pode ser um só, se a matriz for de apenas uma letra, por exemplo. Então para imprimir é um único loop: enquanto tiver algo pra listar vai listando. Nada mais. Exemplo int mostra_tabela(Rascunho* papel) { // mostra as letras na ordem em que apareceram printf("\n\tAs %d letras, na ordem em que apareceram\n\n", papel->n_simbolos); printf("\tLetra Total\n"); int l = 0; int c = 0; // linha e coluna int a_listar = papel->n_simbolos; // esses sao os distintos while (a_listar > 0) { if (papel->total[l][c] != 0) { // uma letra nova printf("\t %3c %3d\n", papel->matriz[l][c], papel->total[l][c]); a_listar = a_listar - 1; // mostrou mais um }; c = c + 1; if (c >= papel->colunas) { c = 0; l = l + 1; }; }; // while() printf("\n\nFim da lista\n"); return 0; // acabou };
  8. o que eu te disse foi que a tabela de letras é muito diferente da matriz e colocar a tabela de letras como uma dimensão a mais da própria só vai complicar, além delas terem que ter o mesmo nome, o que deixa tudo menos legível. Você não pode escrever quantidade [ i ], letra[ i ], porque colocou os valores como uma dimensão a mais da matriz, e assim fica mais difícil de ler: tem que usar o mesmo nome: matriz. Só que não é a matriz. Basta ler os programas que temos aqui. Veja nesse trecho aqui como é mais simples de entender que achou um símbolo novo e aumentou o total deletes e o símbolo é c... if (nova_letra) { // primeira vez de c papel->simbolo[papel->n_simbolos] = c; papel->total[papel->n_simbolos] = 1; papel->n_simbolos += 1; }; uma matriz de M[ A ][ B ][ C ] é um vetor de vetores de vetores. Não há o que fazer sobre isso. É a linguagem e o hardware. O compilador calcula a dimensão total e coloca os caras lá a partir do início, linha por linha. Uma matriz char M[10][10]; é um vetor de 10 vetores de 10 char cada um. M[0] por exemplo é char[10], M[1] é char[10]. Você lê a declaração da direita para a esquerda. C só tem vetores, arrays. Não é FORTRAN. Eu programei por muitos anos em FORTRAN antes de usar C e demorei para aceitar que não existe array multidimensional em C . É a realidade em C. M[0][7] é char. Assim é. a matriz pode estar --- e está nos exemplos que te mostrei --- dentro da struct. Não muda nada escrever papel->matriz[0][0]; ou m_x_n2[contl2][contc2][0] = 0; como no seu programa. struct em C é só um agrupamento de variáveis dentro de um nome só, uma estrutura Usar uma estrutura simplifica a leitura do programa e a passagem de parâmetros, mas pode muito bem passar sem isso, em especial num programa tão simples. Só fica mais chato ficar passando os parâmetros para as funções, e assim mais difícil de ler. Você pode pegar o programa que te mostrei e apagar a struct. É só trocar os parâmetros das funções. Vai funcionar igualzinho em minutos.
  9. @devair1010 Não há exatamente um problema em usar uma matriz tridimensional e não há uma razão para não funcionar assim. Apenas não é uma boa ideia: não acrescenta nada e apenas dá mais trabalho e fica mais difícil de ler o programa, como deve ter percebido comparando os exemplos que temos aqui. Entenda que essas dimensões da matriz nada tem a ver uma com a outra e quando você se afasta dos dados certamente vai ter mais trabalho o primeiro problema já aparece no nome e sentido: uma matriz é apenas um nome e um endereço de início. E você tem que usar essas dimensões da matriz para coisas muito diferentes. Você tem os dados em um plano E a partir deles vai criar uma lista com cada símbolo e o total de vezes em que ele aparece. Esses seriam os outros planos da matriz acontece que esses dados não tem nada a ver com a estrutura da matriz e vai complicar a lógica de seu programa. Imagine uma tabela de 8x8 símbolos, metade 'a' e metade 'Y' e acho que vai entender: você só tem dois valores e eles não tem essa estrutura 8x8 e o nome fica o mesmo então fica difícil de ler e escrever. Notou que em seu programa não se explica que os contadores de símbolos estão lá no segundo plano da matriz E teve que zerar todos? E não há razão para zerar todos, desde que você saiba quantos símbolos distintos tem na matriz. Ela pode ter 100 valores iguais por exemplo. Rascunho typedef struct { int linhas; // o esperado int colunas; char matriz[100]; // maximo 10x10 afinal int n_simbolos; // total de simbolos distintos char simbolo[100]; // a tabela char total[100]; // de simbolos e totais } Rascunho; Eu digitei o programa que eu postei aqui em cima de seu programa, apenas para mostrar como podia ser mais fácil e legível se escrevesse em torno dos dados. E chamei de Rascunho porque era algo simplório escrito apenas para rodar da primeira vez e ser fácil de ler. E olhando acima você "vê" o enunciado e o caminho da solução. Mas algo assim já serviria, já que mostrou os valores certos logo na primeira vez. Mas... typedef struct { int linhas; // o esperado int colunas; char matriz[100]; // maximo 10x10 afinal int n_simbolos; // total de simbolos distintos char total[100]; // de simbolos e totais } PlanoB; Assim estaria melhor porque não há razão para repetir os símbolos ou colocar linha, coluna e mais um índice numa coisa que é só uma lista de totais. Os símbolos já estão na matriz afinal. Isso seria o simples. Mas.. typedef struct { int linhas; // o esperado int colunas; char matriz[10][10]; // maximo 10x10 afinal int n_simbolos; // total de simbolos distintos char total[100]; // de simbolos e totais } OsDados; Isso seria o mais alinhado com o enunciado. Entenda que não existe essa noção de vetor, matriz ou matriz multidimensional em C. Uma matriz de duas dimensões é apenas um vetor de vetores. Uma de 3 é um vetor de vetores de vetores. Nada mais. Todos alocados por linha na memória a partir do endereço inicial, e acessados pelo nome mais um deslocamento. Para duas dimensões essa é a conta M[i * papel->colunas + j] = c; // para acessar M[i,j]; Se você não fizer o compilador vai fazer. A contagem das letras O mais difícil de justificar nessa solução na verdade não é o fato de forçar a tabela de totais em uma dimensão a mais da matriz, numa coisa que não tem essa estrutura e que não deveria ter o mesmo nome. O maior problema é voltar a processar a matriz num loop posterior. Não é eficiente. Se eu fosse corrigir os programas de vocês iria penalizar todas as soluções que tivessem essa ingenuidade incluída. Uma vez que você leu uma letra, não há razão para não tabelar o resultado na hora. Veja como foi feito no exemplo c = getchar(); M[i * papel->colunas + j] = c; // marca a presenca da letra 'c' int nova_letra = 1; for (int i = 0; i < papel->n_simbolos; i += 1) if (c == papel->simbolo[i]) { papel->total[i] += 1; // ja tinha nova_letra = 0; break; // resolvido }; // if() if (nova_letra) { // primeira vez de c papel->simbolo[papel->n_simbolos] = c; papel->total[papel->n_simbolos] = 1; papel->n_simbolos += 1; }; E entenda como é trivial de ler. Como eu disse, sequer é preciso ter um vetor de símbolos e se eu fosse corrigir o meu programa ia descontar algo por ter esse vetor também. Depois eu mostro uma solução usando a terceira estrutura que mostrei @Arthur Bezerra de Oliveira não se preocupe, não sou seu professor disfarçado aqui Pode programar omo achar melhor Poste seu código se ainda precisa de ajuda.
  10. Não havia nada a ser lido no programa. Apenas ia mostrar o resultado da soma. Veja mas mensagens que stdio.h não foi encontrado. Tudo que aparece ali é importante. "fatal error" quer dizer isso mesmo: ele morreu. Sua instalação está com problemas. Sugiro remover e instalar de novo. Quem sabe a partir de um novo download. Não quero entrar em discussões religiosas aqui, mas Code::Blocks não é assim uma boa escolha. Mas antes de se preocupar com o Code::Blocks rode gcc -v em sua máquina e espere ver algo assim... dizendo a versão de gcc que está instalada. Dá pra viver sem o IDE, mas sem o compilador não dá... E depois que mostrar isso pode usar esse comando cd c:\ mkdir teste cd teste copy con teste.c #include <stdio.h> int main(void) { printf("gcc ativo e operante\n"); } F6 gcc teste.c a E espere algo assim E assim vai saber que o compilador esta ok
  11. Sempre é melhor escrever o programa em torno dos dados. Considere, @devair1010, essa estrutura como exemplo: typedef struct { int linhas; // o esperado int colunas; char matriz[100]; // maximo 10x10 afinal int n_simbolos; // total de simbolos distintos char simbolo[100]; // a tabela char total[100]; // de simbolos e totais } Rascunho; Um rascunho como se a gente fosse usar papel e caneta e ir marcando as letras conforme a matriz. Tudo fica muito mais simples. Veja se concorda: Considere as funções int define_tamanhos(Rascunho*); int le_matriz(Rascunho*); int mostra_matriz(Rascunho*); int mostra_tabela(Rascunho*); Imagine o que elas fazem: o óbvio. E marcam no tal Rascunho os valores. main() int main() { Rascunho papel; // nosso papel e caneta papel.n_simbolos = 0; define_tamanhos(&papel); le_matriz(&papel); mostra_matriz(&papel); mostra_tabela(&papel); printf("Tecle ENTER para terminar \n"); getchar(); return 0; } No fundo main() só tem uma variável: o papel pra marcar as letras e a tabela. E as funções vão preenchendo os valores conforme encontram. Como eu expliquei num outro post, não há razão para ler a matriz e depois verificar as letras. Não é eficiente: quando você lê já pode ver se já tinha ou não a letra e fazer as contas, marcando no "papel" . Assim ao final só precisa mostrar a tabela de ocorrências. Veja essa rotina int le_matriz(Rascunho* papel) { // o tamanho da matriz esta no 'papel' que veio como argumento printf("\nMatriz com %dx%d caracteres\n", papel->linhas, papel->colunas); char c = 0; char* M = papel->matriz; // mais fácil pra ler for (int i = 0; i < papel->linhas; i++) for (int j = 0; j < papel->colunas; j++) { printf("Digite o elemento para [%d,%d] : ", i, j); c = getchar(); M[i * papel->colunas + j] = c; // marca a presenca da letra 'c' int nova_letra = 1; for (int i = 0; i < papel->n_simbolos; i += 1) if (c == papel->simbolo[i]) { papel->total[i] += 1; // ja tinha nova_letra = 0; break; // resolvido }; // if() if (nova_letra) { // primeira vez de c papel->simbolo[papel->n_simbolos] = c; papel->total[papel->n_simbolos] = 1; papel->n_simbolos += 1; }; while ((c = getchar()) != '\n' && c != EOF) {}; }; return 0; }; // le_matriz() Apenas um loop para ler a matriz. Mas dentro do loop já marca na tabela a letra (se é nova) ou marca a nova ocorrência (se já tinha). Mais simples e fácil de ler. E mostrar o resultado é trivial int mostra_tabela(Rascunho* papel) { // mostra as letras na ordem em que apareceram printf("\n\tAs %d letras, na ordem de apresentacao\n\n", papel->n_simbolos); printf("\tLetra Total\n"); for (int i = 0; i < papel->n_simbolos; i += 1) printf("\t %3c %3d\n", papel->simbolo[i], papel->total[i]); printf("\n\nFim da lista\n"); return 0; }; Só um loop. Um exemplo de execução: Quantidade de Linhas da matriz [1..10]: 2 Quantidade de Colunas da matriz [1..10]: 4 Matriz com 2x4 caracteres Digite o elemento para [0,0] : a Digite o elemento para [0,1] : c Digite o elemento para [0,2] : d Digite o elemento para [0,3] : F Digite o elemento para [1,0] : G Digite o elemento para [1,1] : a Digite o elemento para [1,2] : c Digite o elemento para [1,3] : s Matriz com 2x4 caracteres a c d F G a c s As 6 letras, na ordem de apresentacao Letra Total a 2 c 2 d 1 F 1 G 1 s 1 Fim da lista Tecle ENTER para terminar Deixei até a "pausa" no final para manter sua tradição. Eis um programa completo
  12. @devair1010 Eu achei aquele complicado com as 3 matrizes e tal, mas agora tem uma possibilidade com apenas duas matrizes, mas de TRÊS dimensões e 17 comandos de loop incluindo um loop de 4 loops for aninhados? Não seria muito para listar as ocorrências? Vou ler tudo de novo
  13. Vou repetir o que eu escrevi sobre isso há pouco nesse tópico: Seu programa está muito complicado sem necessidade. 3 matrizes? Não precisa disso. E não é esperto ler primeiro porque não vai mudar nada. Faça as contas enquanto lê. É mais simples e eficiente. E não precisa sequer de uma matriz para testar. Apenas uma sequência de números. Não é preciso fazer um programa inteiro primeiro. Pode fazer pequenos programas. Ninguém vai te culpar, mesmo porque ninguém vai saber. Projetos grandes são todos escritos assim.
  14. int tam; int menu(void); void inicia(node *PILHA); void opcao(node *PILHA, int op); void exibe(node *PILHA); void libera(node *PILHA); void push(node *PILHA); node *pop(node *PILHA); Apenas vendo as declarações, e a pilha struct Node{ int num; struct Node *prox; }; typedef struct Node node; Não sei como ensinam isso ou que livros servem de texto para esses cursos de estruturas de dados hoje, mas um node não é a pilha, um node não é a lista, uma folha não é a árvore. Mesmo assim 100% dos problemas e mesmos das soluções propostas aqui partem desse princípio. Mas não é assim. C++ oferece suporte a pilhas em STL, como tem em java e outras linguagens. Pode olhar lá para se "inspirar". Os caras que escrevem isso são geniais programadores. Em geral a pilha tem esses métodos, com esses nomes já clássicos - push: coloca um item - pop: tira o item - peek ou top: olha o primeiro (retorna mas não tira) - empty: retorna 1 se vazia - size: retorna quantos tem Dependo da implementação pode ter algo como limit() que devolve a capacidade da pilha. De volta ao seu caso - Todas as funções retornam void e isso é no mínimo um desperdício. Talvez um erro mesmo - inicia() do modo como a pilha foi declarada é provavelmente superfluo. - pop() retorna um ponteiro para node? - os dados são um int? Em geral o que você quer é (void*) claro. Assim pode empilhar qualquer coisa sem mudar uma linha do código. E pode usar a pilha, claro, sem compilar o código de novo. - uma variável global é ruim: é proibido em muitas empresas, condenado por autores e professores, e fonte de problemas em todo lugar em que é usado. Não use isso. Se precisa é porque tem algo errado, como aqui a sua estrutura de dados. Assim funciona em C++ Eis os métodos em C++ Sua implementação supõe a implementação a partir de ponteiros mas nem sempre é assim com pilhas. Muitas vezes é um vetor apenas, porque é muito mais rápido: um vetor alocado dinamicamente com ponteiros para estruturas. E aí prox é um int apenas. Uma alternativa typedef struct { void* dado; struct _n* prox; } _node; typedef struct { int size; _node* stck; } Pilha; Uma diferença óbvia já no inicio é que pode ter mais de uma pilha em um programa, ou mesmo um vetor delas. No seu caso já percebeu que por ter uma variável global tam para controlar algo que é absolutamente interno à pilha você: - só vai poder ter uma pilha - não vai poder usar isso de um modo genérico, tipo incluir isso em todos seus programas que precisem de uma pilha, muito embora seja para isso que essas estruturas existem. E nesse caso aqui você pode inserir qualquer objeto, seja um int ou uma string ou uma struct enorme, em uma pilha P qualquer. Se declarar Pilha pilha[30]; // 30 pilhas E a funções? Uma possibilidade: int dump(Pilha* P); // mostra na tela os valores, pra testar int push(void* item, Pilha* P); // grava na pilha e retorna status int size(Pilha* P); // retorna quantos tem agora int pop(Pilha* P); // remove o elemento de cima void* top(Pilha* P); // retorna o elemento de cima void* peek(Pilha* P); // retorna o elemento de cima int empty(Pilha* P); // retorna 1 se vazia dump() Numa pilha é básico não ter acesso a nada exceto o primeiro elemento, exceto para quem está implementando a estrutura e precisa testar dump() você usa para mostrar na tela o conteúdo da pilha pra ver se está tudo saindo como esperado. O resto é o óbvio. peek() e top são a mesma função. Em C++ teria o construtor da classe, mas em C precisa de algo como Pilha* cria_pilha(); Um construtor. Pense nisso: uma Pilha é algo assim, Genérico. E daí para diante você pode usar em qualquer programa. Passar adiante. Para isso servem essas estruturas: abstrações com dados.
  15. Vou repetir o que eu escrevi sobre isso há pouco... Seu programa está muito complicado sem necessidade. 3 matrizes? Não precisa disso. E não é esperto ler primeiro porque não vai mudar nada. Faça as contas enquanto lê. É mais simples e eficiente. E não precisa sequer de uma matriz para testar. Apenas uma sequência de números. Não é preciso fazer um programa inteiro primeiro. Pode fazer pequenos programas. Ninguém vai te culpar, mesmo porque ninguém vai saber. Projetos grandes são todos escritos assim.
  16. Sua matriz não é tão grande assim, com 10x10 tem claro um máximo de 100 símbolos diferentes, provavelmente menos já que o próprio usuário vai ter que escolher o tamanho e depois digitar as letras uma a uma. Então um par de vetores serviria. E um contador. Algo simples como int letras = 0; //quantas letras? linhasxcolunas int s[100]; // os simbolos int q[100]; // a quantidade de cada um E é só isso. - leia as dimensões - leia os valores e coloque na matriz. Ao mesmo tempo --- claro --- veja se a letra que letra que leu está em s[] que tem letras valores dentro - não precisa por em ordem. o vetor é muito pequeno. Apenas olhe um a um. Como o enunciado aparentemente nada diz, faça o simples: todo símbolo é diferente, um ponto, uma vírgula, um número, 'a' ou 'A'. - se é um símbolo novo apenas coloca no vetor e aumenta o contador - se é um repetido apenas aumente o contador correspondente, q [ ]. - o óbvio: se s[3] vale 'A' e q[3] vale 5 quer dizer o simples: já leu 5 vezes 'A' Só isso. Ao final da leitura você tem todos os resultados. Mostra a matriz e eventualmente entra em um loop onde o usuário pode digitar um símbolo e você diz quantas vezes ele apareceu.
  17. Seu programa tem vários problemas ainda para compilar Você tem um livro? Um manual? Uma apostila? scanf_s() precisa de mais um parâmetro. Esse é o _s da função: para ler %c ou %s ou %[] você precisa passar o tamanho da área... Direto da documentação: char s[10]; scanf_s("%9s", s, (unsigned)_countof(s)); // buffer size is 10, width specification is 9 matriz[j] = ch; Você não pode escrever isso. Veja a declaração: char matriz[10][10];/*Criação da Matriz*/ Então matriz[j] é char[10] e não pode receber um char. Acha que precisava mesmo desse comentário? contar vs Contar São variáveis diferentes e você está usando ao contrário. Precisa mesmo usar duas variáveis assim parecidas? Achava que não ia confundir? Confundiu ... for (int r = 0; r < count_t; r++) { Tem certeza que quer declarar outro r? Já tem essa variável fora do loop. Podia usar nomes mais expressivos para variáveis que não são apenas índices. bool ver = false; /*Variavel lógica usada para verificar se determinado caractere já apareceu*/ Declarou isso dentro de um for então ela só vale aí dentro. Mas tentou usar depois. Corrija essas coisas Seu programa parece complicado demais. Já pensou em escrever mais funções e testar uma a uma?
  18. Não, não é o ';' É como está escrito: class Aviao { public: int velo = 4; }; Seu compilador está reclamando de você escrever int velo=4; que não é assim normal. Inicialização de variáveis deve ser feita no construtor da classe. Ao menos é o esperado em C++ e por isso existe o construtor. Meu compilador até aceitou, mas não é o normal: Você sequer pode usar esse valor que declarou para nada... Aviao não existe: é uma classe apenas. Você não pode atribuir esse valor velo, não pode mostrar na tela, não pode fazer nada. velo só vai existir se declarar algum avião. Em C++ se chama instância da classe. Aviao av[40]; declara 40 deles, todos com velo = 4. Isso é o normal: class Aviao { public: int velo = 4; Aviao() { velo = 4; }; }; Isso é comum no caso de constantes ou argumentos: class Aviao { public: int velo; Aviao() : velo(4){}; Aviao(int velo) : velo(velo) {}; }; No primeiro caso quer dizer que toda instância de Aviao declarada assim terá velo = 4; No segundo caso terá o valor que definir, como em #include <iostream> class Aviao { public: int velo; Aviao() : velo(4) {}; Aviao(int velo) : velo(velo) {}; }; int main() { Aviao a; Aviao b(38); std::cout << a.velo << std::endl; std::cout << b.velo << std::endl; } que vai mostrar 4 38 O ';' depois do > gera um warning mas deve compilar sem problemas. warning C4067: unexpected tokens following preprocessor directive - expected a newline Mesmo que possível, inicializar variáveis no construtor não é boa prática e vai contra os "codelines" em qualquer empresa ou escola. Isso cria um segundo lugar para procurar algo que deveria estar por definição no construtor da classe e assim dificulta entender o programa. Por exemplo tem que saber quem leva vantagem se você inicializar nos dois lugares... Se tem vários construtores que inicializam essa variável e você vai aí e põe outro valor direto na declaração da classe, pode achar que está definindo algo, mas não vai mudar nada. O construtor tem a palavra final. E entenda que os construtores geralmente são declarados em outro arquivo. As classes em geral são escritas aos pares, um header e um arquivo .cpp. E então no header não vai saber o que está havendo.
  19. arfneto

    C Imprimir meses na tela

    Acho que não devia se preocupar com a programação antes dos dados. Escreva seu programa em torno dos dados. Você tem uma ideia do que quer mostrar? Em geral as telas hoje em dia são no formato 16:9 como as TV. Saindo de um formato 4:3 que durou décadas. Então se você tem os dados e uma ideia do que quer apresentar, podia escrever isso em uma planilha ou slide usando um desses programas de apresentação, como os do Google --- Planilhas e Apresentações são dois desses programas. que são grátis e rodam em qualquer navegador, e montar um protótipo com os dados. A partir daí fica muito mais fácil escrever um programa. Use esse formato no planilha ou no Slide para ir distribuindo os dados na tela Uma parte da tela podia ter a série histórica, com cores mostrando a tendência. Uma linha de tendência, os dados de capação e tal. Cores podem também mostrar a tendência dos índices de captação em relação à media. Sobre o programa Acho que não devia usar um menu ou ficar lendo dados da tela. É muito chato pra quem vai usar. Leia de um arquivo. é muito mais simples. Não precisa escrever tudo isso: strcpy_s(meses [1],"Janeiro" ); strcpy_s(meses[2], "Fevereiro"); strcpy_s(meses[3], "Março"); strcpy_s(meses[4], "Abril"); strcpy_s(meses[5], "Maio"); strcpy_s(meses[6], "Junho"); strcpy_s(meses[7], "Julho"); strcpy_s(meses[8], "Agosto"); strcpy_s(meses[9], "Setembro"); strcpy_s(meses[10], "Outubro"); strcpy_s(meses[11], "Novembro"); strcpy_s(meses[12], "Dezembro"); Pode usar assim const char* _mes[12] = { "Janeiro", "Fevereiro", "Marco", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro" }; Mais simples e em tempo de compilação. Não há razão para chamar uma função strcpy_s() para carregar valores que já conhece em um vetor A CADA VEZ QUE RODAR SEU PROGRAMA. Não faz sentido. Veja esses dados de exemplo da SABESP da minha cidade http://mananciais.sabesp.com.br/Situacao Algo assim mais um gráfico talvez ia parecer sério
  20. Isso era pra ser algo simples mas é um inferno. No fundo era pra ser uma simples tabela de look-up onde você tem uma matriz de referência com o código resultante e usa para substituir o valor numérico. Algo como char ref[256]; E você na saída usa ref[ buffer ] e "traduz" a letra lida em buffer. Muito simples e super rápido. São 256 possibilidades por byte, então é só preencher e já era. Postei códigos aqui que fazem isso. Claro, depois de feita a substituição teria que ter algum tipo de dicionário para você pesquisar a palavra, se é isso que precisa fazer. Na prática não há como garantir que ao abrir isso alguém vá estar vendo a mesma representação do caracter que você viu. Vai depender da fonte em uso, da página de código em uso no computador e como o cara vai abrir isso: no Terminal do windows? Num editor de texto? Numa console? Isso é o d1@b0. Não faça se não for mesmo importante ou pago ou os dois. Veja um pedaço do seu arquivo aberto no bloco de notas no computador que estou usando Está certo sobre o 105? Acima você vê parte do problema. Pode seer que a fonte em uso não tenha as letras que quer ou tenha outra representação para o símbolo. Veja no Windows esse aplicativo: Por exemplo essa "letra" 26 14 é perfeitamente legal. E meiga. Mas vai sair na tela? Pode ser... De todo modo entenda que vai ser preciso saber qual fonte está em uso no momento e também a página de código. E também esse lance aí no link acima: novos recursos da console. E também se está usando uma versão recente de Windows ou Linux. Unicode Só que seu arquivo está codificado em Unicode. UTF-8. E tem uma marca nele, algo chamado BOM, que vem logo no início e é opcional. Claro que se é opcional e não estiver lá não dá pra saber a codificação do arquivo. Claro que também se você não ler como tal não vai saver o que é. Só problema. E UTF-8 é multi-byte e então lá se foi a tabela de referência: os "letras" podem ser mais de 150.000 delas e podem ter 1, 2, 3 ou 4 bytes cada uma. Então a tabela de referência teria que ser algo assim char ref[256][4] // ou talvez char* ref[155]; // no seu caso wchar_t ref[256]; // pode ser também Seria preciso saber o propósito e aí sim criar uma solução. Mas não é certo que vá funcionar a menos que controle a fonte, a página de código e talvez outros parâmetros. De volta ao arquivo Esse programa C #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> int main(int argc, char** argv) { const unsigned char BOM[3] = { '\xEF', '\xBB', '\xBF' }; char file_name[64] = { "CharTable.txt" }; if (argc > 1) strcpy(file_name, argv[1]); FILE* one = fopen(file_name, "r+b"); if (!one) return -1; unsigned char buffer[64]; int n = fread(buffer, 1, 3, one); if (n != 3)return -2; if (memcmp(buffer, BOM, 3) != 0) { printf("Marca BOM nao encontrada em '%s'\n", file_name); fclose(one); return 0; }; printf("Marca UTF-8 encontrada\n"); char st = 0; n = fread(buffer, 1, 1, one); if (n != 1) return -1; while (!feof(one)) { // a = b switch (st) { case 0: if (buffer[0] == '=') { st = 1; printf("= [ "); } else { printf("%c", buffer[0]); } break; case 1: if (buffer[0] == '\r') { st = 0; n = fread(buffer, 1, 1, one); printf(" ]\n"); } else { printf("0x%0X ", buffer[0]); }; // if() break; default: break; }; // switch() n = fread(buffer, 1, 1, one); }; fclose(one); return 0; } Deve ajudar a entender. Para o seu arquivo ele mostra: Marca UTF-8 encontrada 0= [ 0xF0 0x9F 0x8C 0x80 ] 1= [ 0x21 ] 2= [ 0x20 ] 3= [ 0x22 ] 4= [ 0x23 ] 5= [ 0xE2 0x86 0x91 ] 6= [ 0x25 ] 7= [ 0x26 ] 8= [ 0x27 ] 9= [ 0x28 ] 10= [ 0x29 ] 11= [ 0x2A ] 12= [ 0x2B ] 13= [ 0x2C ] 14= [ 0x2D ] 15= [ 0x2E ] 16= [ 0x2F ] 17= [ 0x30 ] 18= [ 0x31 ] 19= [ 0x32 ] 20= [ 0x33 ] 21= [ 0x34 ] 22= [ 0x35 ] 23= [ 0x36 ] 24= [ 0x37 ] 25= [ 0x38 ] 26= [ 0x39 ] 27= [ 0x3A ] 28= [ 0x3B ] 29= [ 0xE2 0x86 0x90 ] 30= [ 0x3D ] 31= [ 0xE2 0x86 0x92 ] 32= [ 0x3F ] 33= [ 0xE2 0x86 0x93 ] 34= [ 0x41 ] 35= [ 0x42 ] 36= [ 0x43 ] 37= [ 0x44 ] 38= [ 0x45 ] 39= [ 0x46 ] 40= [ 0x47 ] 41= [ 0x48 ] 42= [ 0x49 ] 43= [ 0x4A ] 44= [ 0x4B ] 45= [ 0x4C ] 46= [ 0x4D ] 47= [ 0x4E ] 48= [ 0x4F ] 49= [ 0x50 ] 50= [ 0x51 ] 51= [ 0x52 ] 52= [ 0x53 ] 53= [ 0x54 ] 54= [ 0x55 ] 55= [ 0x56 ] 56= [ 0x57 ] 57= [ 0x58 ] 58= [ 0x59 ] 59= [ 0x5A ] 60= [ 0x5B ] 61= [ 0xC3 0xA9 ] 62= [ 0x5D ] 63= [ 0xE2 0x86 0x93 ] 64= [ 0x5F ] 65= [ 0xC2 0xB4 ] 66= [ 0x61 ] 67= [ 0x62 ] 68= [ 0x63 ] 69= [ 0x64 ] 70= [ 0x65 ] 71= [ 0x66 ] 72= [ 0x67 ] 73= [ 0x68 ] 74= [ 0x69 ] 75= [ 0x6A ] 76= [ 0x6B ] 77= [ 0x6C ] 78= [ 0x6D ] 79= [ 0x6E ] 80= [ 0x6F ] 81= [ 0x70 ] 82= [ 0x71 ] 83= [ 0x72 ] 84= [ 0x73 ] 85= [ 0x74 ] 86= [ 0x75 ] 87= [ 0x76 ] 88= [ 0x77 ] 89= [ 0x78 ] 90= [ 0x79 ] 91= [ 0x7A ] 92= [ 0x7B ] 93= [ 0xF0 0x9F 0x90 0x9B ] 94= [ 0x7D ] 95= [ 0x7E ] 96= [ 0xC3 0x89 ] 97= [ 0xC3 0xA9 ] 98= [ 0xC3 0xAA ] 99= [ 0xC3 0xAA ] 100= [ 0xC3 0xAD ] 101= [ 0xC3 0x8D ] 102= [ 0xC3 0xAF ] 103= [ 0xC3 0x8F ] 104= [ 0xC3 0x81 ] 105= [ 0xC3 0x9A ] 106= [ 0xC3 0x80 ] 107= [ 0xC3 0x99 ] 108= [ 0xC3 0x88 ] 109= [ 0xC3 0x82 ] 110= [ 0xC3 0x94 ] 111= [ 0xC3 0x8A ] 112= [ 0xC3 0x9B ] 113= [ 0xC3 0x83 ] 114= [ 0xC3 0x91 ] 115= [ 0xC3 0x84 ] 116= [ 0xC3 0x85 ] 117= [ 0xC3 0x8E ] 118= [ 0xC5 0xB8 ] 119= [ 0xC3 0x93 ] 120= [ 0xC3 0x9F ] 121= [ 0xC3 0x96 ] 122= [ 0xC3 0x9C ] 123= [ 0xC5 0x92 ] 124= [ 0xC3 0x86 ] 125= [ 0xC3 0x98 ] 126= [ 0xC3 0x95 ] 127= [ 0xC3 0x8C ] 128= [ 0xC3 0x87 ] 129= [ 0xC3 0xA1 ] 130= [ 0xC3 0xA0 ] 131= [ 0xC3 0xBA ] 132= [ 0xC3 0xB9 ] 133= [ 0xC3 0xA8 ] 134= [ 0xC3 0xA2 ] 135= [ 0xC3 0xB4 ] 136= [ 0xC3 0xAA ] 137= [ 0xC3 0xBB ] 138= [ 0xC3 0xA3 ] 139= [ 0xC3 0xB1 ] 140= [ 0xC3 0xA4 ] 141= [ 0xC3 0xA5 ] 142= [ 0xC5 0x93 ] 143= [ 0xC3 0xAE ] 144= [ 0xC3 0xBF ] 145= [ 0xC3 0xB3 ] 146= [ 0xC3 0xB2 ] 147= [ 0xC3 0xB6 ] 148= [ 0xC3 0xBC ] 149= [ 0xC3 0xA6 ] 150= [ 0xC3 0xB8 ] 151= [ 0xC3 0xA7 ] 152= [ 0xC3 0xAC ] 153= [ 0xC2 0xBF ] 154= [ 0xC2 0xA1 ] 155= [ 0xC3 0x92 Sim, eu esqueci de finalizar o último valor Mas é o valor dos bytes em hexadecimal que estão na sua tabela e vão corresponder aos "code points" em Unicode. E você vê que alguns tem 1 byte. Outros 2, 3 ou 4. É muito chato.
  21. Muito embora quase tudo que está lá ainda seja válido, o livro de Charles Petzold deve ser visto com cuidado. Imagino que não vá ler um livro de mais de 1.200 páginas, mas entenda que ele foi escrito quando a maioria dos PC rodavam Windows 95. Windows NT era novidade, internet não era quase nada. Não havia DVD, mp3, Unicode estava começando e era muito diferente.coisas assim. É um livro de 1998. Há muitos novos controles no Windows, a API cresceu de um modo inacreditável. Novas API surgiram e sumiram, coisas como MFC e dotNet. É interessante. Mas ninguém usa isso há décadas. aplicativos para desktop praticamente se foram quando são escritos raramente o são em C ou C++ quando são escritos nessa linguagem muitas vezes são para instrumentos e não para desktops de fato. Coisas como avionics, medicina, carros e eletrônica embarcada. E são escritos a partir de frameworks como Qt, wxWidgets, GTK+ ou SDL, Directx ou OpenGL. Os jogos são um caso a parte mas tem os frameworks e game engines a parte também. nos últimos anos tem tido muito interesse em aplicativos ara desktop em modo texto, por causa da migracão dos desktop para a nuvem. Em geral software em torno de administração de servidores que estão migrando aos milhões para Azure, Google CLoud , Amazon e outros hosts. E não tem interface gráfica.
  22. Sim, tem variáveis globais e é uma ideia ruim. É proibido em muitos lugares e é fonte certa de problemas. Num for todos os comandos são opcionais for( ;; ); Esse comando é perfeitamente legal. Apenas os '; ' são obrigatórios. O que você não especificar não acontece. Só isso. Um programa com essa linha apenas vai ficar nisso para sempre, mas está formalmente correto. Um loop assim for ( ; i<0 ; ) funcao(); É um while(i<0) e vai chamar a funcao() enquanto isso valer. Voltando ao tópico Esse programa vai dar muito trabalho para funcionar assim não devia ter variáveis globais. É uma bobagem. É difícil garantir o que vai ter em dias_dir a cada vez que entra em um loop desses por exemplo. E mesmo que esteja certo é o d1@b0 manter um programa assim funcionando a lógica das colunas está fixa e é um erro. a lógica de imprimir em colunas está misturada com o fato de ser um calendário e é um outro erro. Esses "números mágicos": todos vão dar problema. 3,7,5,6,13,20,27 tudo constante... Essa é a unidade de trabalho do programa ----------------------------- XXXXXXXXXXXXXXXXXXXXXXXXXXX ----------------------------- dom seg ter qua qui sex sab 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 Há claro muitas maneiras de fazer isso. Mas entenda que isso já foi feito assim como está no exemplo para não dar trabalho: todos os meses tem 6 semanas. Basta rodar a sequência pra direita até encaixar o dia da semana e ir preenchendo com "--" o resto dos dias. Por isso falei de ir escrevendo em cima de um "rascunho". Uma função minimalista que faz isso podia ser declarada char prepara_mes(char dia_s, char m, int ano, char* fill, FILE* F) com dia_s entre 0 e 6 sendo zero para domingo até 6 para sábado, m para o mês para acertar os dias de fevereiro, ano para, digamos, o ano, porque precisa saber se é bissexto, fill é uma string que pode ser "--", e F apontando para um arquivo aberto onde a função vai empilhando os meses um depois do outro. Todos com 10 linhas cada um, mas sem escrever uma constante no programa. E a função retorna um char entre 0 e 6. Pra que? Simples: o primeiro dia do mês seguinte. Assim pode usar para um calendário de 3 meses, ou de março a março, ou de 18 meses ou qualquer coisa. Não faz diferença. Para o ano inteiro de 2005 por exemplo // 2005 comecou em um sábado char dia_s = 6; int ano = 2005; const char* fill = " "; for (int i = 0; i < 18; i += 1) dia_s = prepara_mes((char)dia_s, i + 1, ano, fill, F); Nesse exemplo deixa em branco os dias ao invés de colocar os "--" que eu acho um pouco feio. No programa cal do Linux é assim. Lá em 3 colunas e com espaços. Eu postei um exemplo. E para transpor é uma operação matemática, não depende do calendário ou do conteúdo. E eu postei uma função que faz isso também, para qualquer número de colunas. Mas não vou repetir aqui tudo de novo. O endereço do post está acima. Juntando os dois sai o calendário, em 1, 2, 3, 12 ou 20 colunas. Um bonus: char primeiro_dia(int y) { // metodo de Sakamoto 1992 int m = 1, d = 1; static int t[12] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 }; y -= m < 3; return (y + y / 4 - y / 100 + y / 400 + t[m - 1] + d) % 7; }; Essa rotina faz o que está escrito aí e determina o dia que faltava pra fechar a conta. pro Sakamoto!
  23. Tem lido os posts no tópico que você mesmo postou? Tem muitas coisas lá. No tópico #9 por exemplo eu postei um programa que converte isso em QUALQUER NÚMERO DE COLUNAS. Duas, por exemplo. Em seu programa criou 12 vetores praticamente idênticos. Acha que precisava mesmo disso? E entende que o fato de pegar os meses e por lado a lado nada tem a ver com o calendário? Podia ser qualquer coisa. Exemplo (A) (B) (C) (D) (E) (F) Em duas colunas se o "mês" tivesse 3 linhas? (A)(D) (B)(E) (C)(F) Sugiro ler os posts lá no outro tópico. Porque abriu outro tópico sobre o mesmo exato problema 5 dias depois?
  24. E? Entendeu o que eu expliquei? Não respondeu nada

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...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!