Ir ao conteúdo

arfneto

Membro Pleno
  • Posts

    6.526
  • Cadastrado em

  • Última visita

Tudo que arfneto postou

  1. Não é que atrapalhe. Veja assim: você sempre pode escrever (x) ou (1 + x - 1) ou (1*x) só não faz isso porque não faz diferença.
  2. Um exemplo: imagine seu registro declarado assim em #include "memory.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include "malloc.h" struct registro { int RG; char nome[20]; char sobrenome[20]; }; typedef struct registro Registro; // fim de meu_registro.h Mas você ter um outro assim #include "memory.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include "malloc.h" struct registro { int CPF; int RG; char CEP[9]; char nome[20]; char sobrenome[20]; }; typedef struct registro Registro; // fim de meu_registro2.h E imagine suas rotinas da lista declaradas em minha_lista.h #include "meu_registro.h" struct lista { Registro* r; struct lista* proximo; }; // Lista typedef struct lista Lista; int apaga_registro( int(*)(Registro*, Registro*), Registro*, Lista**); int da_um_fim_na_lista( Lista**); int insere_ao_final( Registro*, Lista**); int insere_na_ordem( int (*)(Registro*, Registro*), Registro*, Lista**); Registro* pesquisa_registro( int(*)(Registro*, Registro*), Registro*, Lista**); int remove_item( Lista*, Lista**); int remove_registro( int(*)(Registro*, Registro*), Registro*, Lista**); // fim de minha_lista.h Porque isso? Imagine agora que essas funções de lista.h trabalham só com a lista em si e os ponteiros para Registro. Então você pode usar essas funções para resolver todos os problemas de listas encadeadas simples que tenha. Sem ter que mudar nada. Apenas altera o header que descreve o Registro. Por exemplo, da_um_fim_na_lista() percorre a lista e vai apagando todos os registros e os nós da lista em si, até o último ponteiro, e não precisa saber o que tinha dentro. insere_na_ordem() por exemplo insere os registros na ordem na lista, classificados por qualquer campo. Como por RG no primeiro ou por CPF ou CEP no segundo exemplo. E você não precisa mudar nada nas funções se mudar de Registro Espero que ajude a entender a razão, mesmo sem ler uma implementação dessas coisas. Notei que falta uma função genérica para percorrer a lista ., Depois vou acrescentar uma. Já fiz algo assim umas vezes. Essas funções vem da funcionalidade primária que se procura nessas estruturas, e tem uma abreviatura: CRUD --- na verdade tem outras --- para Create, Read, Update e Delete e no final pense que podia declarar as funções assim #include "meu_registro_v.h" struct lista { void* r; struct lista* proximo; }; // Lista typedef struct lista Lista; int apaga_registro(int(*)(void*, void*), void*, Lista**); int da_um_fim_na_lista(Lista**); int insere_ao_final(void*, Lista**); int insere_na_ordem(int (*)(void*, void*), void*, Lista**); void* pesquisa_registro(int(*)(void*, void*), void*, Lista**); int remove_item(Lista*, Lista**); int remove_registro(int(*)(void*, void*), void*, Lista**); // fim de minha_lista_v.h E aí sequer precisa chamar a estrutura de Registro e você tem uma implementação abstrata para lista que funciona para qualquer coisa porque todos os ponteiros foram trocados de Registro* para void*. Nada original porque isso que as bibliotecas fazem afinal. Para um exemplo bem melhor que o meu veja a função qsort() do C em stdlib.h por exemplo.
  3. Esse é um problema de lógica e não de C ou C# ou C++ Você listou o tema como C++. Em C++ você tem filas e outras estruturas de dados que podem ajudar bem, fazendo quase todo o serviço. Mas a julgar pelo código deve ser em C. Eu sempre recomendo isso e aqui vou escrever de novo: não acho que deva perder tempo lendo entrada ou criando menus e formatando texto ou cores, ou mesmo deslocando cursor antes de ter a lógica disso funcionando. Vou tentar mostrar mais a seguir. Estrutura de dados Quanto mais perto seus dados estiverem do modelo de atendimento mais fácil vai ser programar a solução. Claro que há sempre um milhão de maneiras de tratar isso, mas vou te descrever uma maneira "mais matemática do que programática" de fazer isso. Afinal existe uma disciplina chamada Teoria das Filas até. @Dcosta7 sugeriu usar uma fila para cada atendimento e é perfeitamente possível usar isso. E em seu programa tem dois vetores que parecem indicar que você está fazendo isso. Eu vou sugerir usar uma única fila Você pode ver as filas de dois lados: do lado do servidor ou do lado do cliente. Você está programando o recurso do lado do servidor. Os outros elementos são o tempo de atendimento e o tempo em si. Algumas regras A cada dois clientes sem prioridade você deve atender um prioritário Pode não haver cliente prioritário Pode haver apenas clientes prioritários Pode não ter ninguém pra atender Então se tem alguém pra atender entra a noção da fila de prioridade e você tem que escolher entre as regras mas também entre o mix da fila no momento em que o servidor está livre, o único caixa digamos, por simplicidade. Se você numerar os atendimentos a partir do início--- e isso é trivial porque estamos usando um computador --- eles vão estar assim 1,2,3,4,5,6,7,8,9,10 e você deve atentar para os atendimentos 3, 6, 9, ... para ver a fila de clientes que solicitaram prioridade. Mas isso tem uma fórmula: (numero_do_atendimento % 3 == 0) Lembro que o operador % --- módulo --- é o resto da divisão do primeiro operando pelo segundo, como 17 % 3 = 2 porque 17 = 3*5 + 2; // exemplo Desculpe se estou escrevendo algo óbvio. Sua estrutura tem uma capacidade, como tem uma capacidade o lugar onde os caras vão ficar na fila. Você está usando 200. Então esse é o limite. Como já alocou os 200 direto pode usar duas variáveis para marcar o óbvio: o início e o final da fila. E usar o índice do vetor como a clássica "senha" do cliente. Quando você vai atender pode ser uma função atendimento(numero_do_atendimento, fila) ; por exemplo. Você incrementa o número e faz aquela conta (numero_do_atendimento % 3 == 0) e se for a hora chama o próximo prioritário se tiver algum. Se não for chama o próximo apenas. Por isso sugiro usar uma única fila... E como controlar os atendimentos e prioridades? Pode ser algo bem ingênuo: não sei de sua familiaridade com estruturas e ponteiros e vetores de mais de uma dimensão então vamos ficar com o minimalista: 200 senhas e um status, onde status pode ser por exemplo 0 para atendimento normal, 1 para atendimento prioritário e -1 para cliente já atendido. Isso já deve ser suficiente para controlar as duas filas (em uma) e as prioridades. E a sua fila tem um ponteiro para o próximo atendimento e para o último atendimento. Dois valores positivos. Algo como: const int NORMAL = 0; const int PRIORIDADE = 1; const int VAGO = -1; int fila[200]; int proximo_cliente = -1; int ultimo_cliente = -1; Porque os dois ponteiros? porque assim você sabe quantos clientes tem na fila a cada momento e pode usar o vetor como circular, para não ter que ficar controlando nada ou deslocando os elementos no vetor. Ao começar o atendimento você marca todas as posições como VAGO. Quando alguém entra na fila é cadastrado na próxima posição livre no vetor, e o status normal ou prioritário. Isso é trivial porque é só preencher o índice do vetor correspondente à senha. Com o status correto. Quando vai haver um atendimento você vê pelo número de atendimento se é hora de buscar preferencialmente alguém com status prioritário. Se tem atende esse e marca lá no vetor como atendido porque pode estar bem adiante na fila, claro. Se não tem ninguém para atender, não faz nada. Se estourou a fila para o atendimento até atender alguém. É a realidade Ao invés de ficar lendo --- porque vai levar uma eternidade para testar a fila como já expliquei ou você já descobriu --- crie uma lista de serviço, como um vetorzinho em main() que entra com os atendimentos e chegadas para você poder progredir rápido, ao invés do menu ultra chato e lerdo. E use uma fila de uns 5 caras no máximo Se não entendeu o que expliquei, ou não sabe implementar mas se interessou, escreva de novo. É bem simples.
  4. Parece que falta um índice em inicializa()... Eu não me preocuparia em ficar desenhando coisas na tela ou mesmo ficar limpando a tela antes de resolver o problema em si. Sempre recomendo isso. Ou mesmo pegar entrada do usuário e tal. Essas coisas não agregam nada e só fazem você perder tempo de desenvolvimento da lógica e implementação em si. [palpite] Em várias partes do programa acessa essa matriz com um único índice, mas parece que era pra ter dois. Está certo do que está fazendo Monnica/Danilo? Ainda não entendi qual a dúvida. Isto está funcionando?
  5. Olá Acho que sabe que tem algo errado com o seu post, certo? Não há quebras de linha no código Você também não disse o que está errado ou se tem alguma dúvida, então vai ser difícil ajudar
  6. Se precisa replicar o que está na tabela apenas precisa ler o novo valor de x dentro do loop. Entenda que esse programa não tem memória: a cada leitura os valores tem que ser imediatamente processados: verifica se é o mínimo, incrementa o número de sequência, salva o o número de sequência e o valor se for o novo mínimo. Note que em C tem valor, INT_MAX que você pode usar para facilitar. Se seu compilador não reconhecer o valor talvez deva usar #include "limits.h" onde tem muitas constantes que podem ser úteis. MAX_INT é maior que qualquer número que o usuário pode digitar então pode usar int minimo = INT_MAX; e assim não ter que controlar se já leu ou não algo. Claro, tem um INT_MIN também Se não precisa replicar exatamente a tabela, pode usar um único loop e não precisaria repetir a leitura antes e depois do loop. Mais simples Se precisar veja o conteúdo de limits.h
  7. Olá! Bom que funcionou Evite essa construção aí. Não faz sentido. É como escrever 1*x/x. & extrai o endereço e * o valor do endereço. Pense bem: &*x hão seria x?
  8. arfneto

    C++ mega_sena em funçoes c++

    Terminou o programa? Em C++ você provavelmente criaria uma classe para cada jogo, e no construtor de cada classe você passaria os parâmetros para a geração dos conjuntos de apostas... E podia ter um método sorteio() para gerar um sorteio e conferir as apostas geradas
  9. Olá! resolveu o exercicio?
  10. Olá! quando tem dúvidas sobre o código deve postar também as declarações, certo?
  11. Olá Escreva num papel as coordenadas que vai usar para imprimir e verá o loop que tem que usar. Mas entenda que precisa reservar espaços para o que NÃO vai imprimir... A cada linha vai imprimir o mesmo número de caracteres, apenas quase todos vão ser brancos...
  12. Você precisa de uma estrutura de dados para representar isso aí na memória do computador. @Mateus Elias , como disse @devair1010 Pode ser uma lista, um vetor, qualquer coisa. Se possível algo que possa manter ordenado certo? Assim os relatórios vão refletir alguma ordem, tipo documento, data de criação, nome... E crie um esquema que trate a possível ausência do arquivo de entrada ou de saída ou ambos. E não grave no mesmo arquivo porque pode perder tudo certo? Você pode ter 0 registros na entrada, o usuário cadastra dois, apaga os dois e encerra, então precisa decidir se vai gerar esses arquivos mesmo vazios.
  13. Olá Você pode acessar esses valores da mesma maneira que usou em scanf() por exemplo. Não há diferença alguma. char PrimeiroNome[15]; char UltimoNome[15]; PrimeiroNome é um char[15]; O primeiro caracter deve estar em PrmeiroNome[0] e é claro um char. char inicial = 'C'; if ( PrimeiroNome[0] == inicial ) { // este comeca com a inicial desejada } Ou talvez if ( toupper(PrimeiroNome[0]) == inicial ) { // este comeca com a inicial desejada } Para não ter que se preocupar com maiúsculas e minúsculas
  14. Olá! Provavelmente seu professor está se referindo à especificação %*s de formato para fscanf(), que faz com que a rotina leia e despreze os caracteres até o próximo espaço, o que consumiria assim o colchete e o que mais tiver antes dos dígitos.
  15. @William Dias Deixe ver se eu entendi: eu te disse que você está perdendo tempo escrevendo assim, e você disse que é uma ideia interessante mas vai ver depois. Então se eu estiver errado não vai fazer diferença MAS se eu estiver certo você vai perder muito mais tempo até ter tempo para descobrir que eu estou certo e o seu tempo se foi? Eu acho programação algo complexo. E alguns problemas então... Bem complexos. E programar problemas complexos é então sempre um desafio. Sim. Mais uma prova de que estou certo: tire isso do código que trata a lista. Implemente a lista e teste tudo. Depois você trata de ler e aí resolve isso. O sistema tem funções que listam o conteúdo de um diretório, basta você ler o conteúdo e mostrar na tela para o usuário escolher o arquivo de entrada. Faça isso depois. As funções estão em dirent.h. Insisto: não faça as duas coisas ao mesmo tempo E insira no fim da lista. Já expliquei porque: na saída precisa preservar a ordem. Depois se precisar mostro um exemplo de código Seu código está bom mas está pouco genérico e vai --- como já está --- ter problemas com isso: tire do código da lista essas coisas de ler e abrir arquivos
  16. Por isso perguntei se você tinha escrito também o diagrama, como parte do execício. Trata-se de um exemplo bem ruim. Deviam ter ficado com os clássicos: classe carro, classe animal, classe cachorro , classe poodle... Paciência. Mais um enunciado ruim. Na minha opinião, claro. Mas tenho a mãe natureza do meu lado: estamos falando de abstração do ciclo de vida afinal. Inacreditável esse exemplo. Pois é: mais um sinal de que está errado o conceito. Deixe o responsável como criança mesmo e depois no programa promova a instância para adulto pra você poder continuar com o desenvolvimento. Alguém vai resolver isso depois. Não é culpa sua. Mas não perca tempo.
  17. @William Dias Não rodei seu código ainda, mas entendo que está tentando inserir sempre no início e sua lista só tem ponteiros pra frente. Em geral não é isso que você quer. Porque? A razão é simples: você só tem ponteiros para frente mas você quer ser capaz de reproduzir a estrutura de entrada depois de ter montado a lista, por exemplo para reproduzir a tal tabela NxN igualzinho estava no arquivo. Inserindo no início eles vão ser lidos ao contrário... Os N campos de que fala são esses 3 apenas, nome sobrenome e RG? e sua lista vai ter MxN estruturas dessas com os 3 campos? Talvez fosse melhor postar as estruturas em questão. Mais um palpite: Eu sempre recomendo isso: não misture as coisas. Você tem uma função Lista* InsereTxt( Lista* l); E essa função abre arquivos e lê arquivos e tal. Pense numa função assim Lista* insereRegistro( Lista* lista, Registro* registro); E pense se ela não faria sua vida mais simples. E antes de tudo escreva uma função int mostra_lista( Lista* inicio ); Que mostra um registro da lista por linha e retorna o total de itens lidos para você comparar com o que imagina ter inserido... Assim na hora de testar não perde tempo lendo arquivos e formatando dados e eventualmente tratando erros que nada tem a ver com a estrutura de dados em si. Do modo como escreveu não está errado, mas é pouco produtivo: até o nome do arquivo é constante. E para mudar o teste você tem que editar o arquivo e salvar os dados e rodar de novo... Acho que entendeu Veja esse header por exemplo #define _CRT_SECURE_NO_WARNINGS #include "memory.h" #include <stdio.h> #include <stdlib.h> #include <string.h> struct registro { int RG; char nome[20]; char sobrenome[20]; }; typedef struct registro Registro; struct lista { Registro r; struct lista* proximo; }; // Lista typedef struct lista Lista; int insere_3_campos(char[], char[], int, Lista*); int insere_registro(Registro*, Lista*); int mostra_lista(Lista*); Pode ser algo parecido com o seu caso. Veja as duas funções insere_: com elas você pode inserir campos na sua lista e APENAS testar sua lista inserindo a partir dos campos ou a partir da estrutura já montada. E veja esse programa int main(int argc, char** argv) { Registro modelo; // "template" de registro: modelo Registro* pModelo = &modelo; // ponteiro para o modelo Lista a_lista; // nossa lista de teste Lista* pLista = &a_lista; // um ponteiro para a lista int n; n = mostra_lista(pLista); // vazia printf("mostra_lista() retornou %d\n", n); // monta um registro padrão, "Jhonny Cash", RG = 0 strcpy(modelo.nome, "Jhonny"); strcpy(modelo.sobrenome, "Cash"); int rg = 1; for (int i = 0; i < 3; i+=1, rg+=1) { modelo.RG = rg; insere_3_campos(modelo.nome, modelo.sobrenome, modelo.RG, pLista); } n = mostra_lista(pLista); // vazia printf("mostra_lista() retornou %d\n", n); for (int i = 0; i < 3; i+=1, rg+=1) { modelo.RG = rg; insere_registro(&modelo, pLista); } n = mostra_lista(pLista); // vazia printf("mostra_lista() retornou %d\n", n); return 0; } // end main() Ele pega um modelo de estrutura e testa a inserção com as duas rotinas, usando o modelo e numerando o RG de um em um pra poder testar se a função que mostra está preservando a ordem e não duplicando nada. Talvez a descrição correta seria que ao numerar os registros inseridos no teste você verifica se a rotina de inserção é estável. Estável quer dizer que ela preserva a ordem de entrada para itens idênticos. Eis o que esse programa mostra mostra_lista() retornou -2 insere_via_3_campos('Jhonny' 'Cash' [1]) insere_via_3_campos('Jhonny' 'Cash' [2]) insere_via_3_campos('Jhonny' 'Cash' [3]) mostra_lista() retornou -2 insere_registro('Jhonny' 'Cash' [4]) insere_registro('Jhonny' 'Cash' [5]) insere_registro('Jhonny' 'Cash' [6]) mostra_lista() retornou -2 Ainda sem código nenhum! Mas já implementa vários conceitos. Espero que tenha compreendido. Repito: acho que deve inserir no FINAL da lista os novos elementos Não se esqueça de salvar o endereço de início da lista. Eis o programa inteiro caso queira inserir seu código nesse mecanismo #define _CRT_SECURE_NO_WARNINGS #include "memory.h" #include <stdio.h> #include <stdlib.h> #include <string.h> struct registro { int RG; char nome[20]; char sobrenome[20]; }; typedef struct registro Registro; struct lista { Registro r; struct lista* proximo; }; // Lista typedef struct lista Lista; int insere_3_campos(char[], char[], int, Lista*); int insere_registro(Registro*, Lista*); int mostra_lista(Lista*); int main(int argc, char** argv) { Registro modelo; // "template" de registro: modelo Registro* pModelo = &modelo; // ponteiro para o modelo Lista a_lista; // nossa lista de teste Lista* pLista = &a_lista; // um ponteiro para a lista int n; n = mostra_lista(pLista); // vazia printf("mostra_lista() retornou %d\n", n); // monta um registro padrão, "Jhonny Cash", RG = 0 strcpy(modelo.nome, "Jhonny"); strcpy(modelo.sobrenome, "Cash"); int rg = 1; for (int i = 0; i < 3; i+=1, rg+=1) { modelo.RG = rg; insere_3_campos(modelo.nome, modelo.sobrenome, modelo.RG, pLista); } n = mostra_lista(pLista); // vazia printf("mostra_lista() retornou %d\n", n); for (int i = 0; i < 3; i+=1, rg+=1) { modelo.RG = rg; insere_registro(&modelo, pLista); } n = mostra_lista(pLista); // vazia printf("mostra_lista() retornou %d\n", n); return 0; } // end main() int insere_3_campos(char nome[], char sobrenome[], int RG, Lista* lista) { printf("insere_via_3_campos('%s' '%s' [%d])\n", nome, sobrenome, RG ); return 0; } // end insere_3_campos() int insere_registro(Registro* r, Lista* l) { printf("insere_registro('%s' '%s' [%d])\n", r->nome, r->sobrenome, r->RG ); return 0; } int mostra_lista(Lista* lista) { if ( lista == NULL) return -1; return -2; }
  18. Olá @Cortella Confesso que não li com atenção o código ainda, mas se foi você que definiu as classes, pergunto: se Idoso é derivado de Adulto porque não seguir a natureza e derivar o Adulto de Crianca? Um Adulto poderia acrescentar Criancas privadas e um idoso poderia acrescentar por exemplo um cartao INSS privado e instâncias de Medicamentos, INSS, sei lá --- ok essa foi pobre --- e no construtor de adulto se poderia validar a idade ou fazer uma chamada a um método de validação de maturidade --- ok também foi pobre Isso //Pre-Condicao: Nao pode ser instanciado como Usuario Usuario(int id,string nome,int idade,float saldo); é pra dizer que Usuario é abstrato?
  19. A documentação da Microsoft --- MSDN --- é impressionante. E da IBM também. E o site do StackOverflow. E o cplusplus.com E o YouTube
  20. Muito bom! Nem tive tempo de olhar
  21. Muito bem. Note que não é que você não precise: você não tem alternativa. É isso que passa de todo modo: o endereço de início da estrutura. Se declarar igual dos dois lados então vai funcionar. Só que nem sempre você pode fazer isso. Pensou mesmo no programa que te mostrei? Rodou aquilo? Lá você pode ver que a mesma área de 12 int pode ser vista como matriz[12] ou matriz[2][6] ou matriz[3][4] e tal...
  22. Olá Felipe Imagino que já tenha terminado o programa, mas de todo modo veja essa função char* le_algo( const char* instrucao, const char* mensagem, const unsigned short tam, char* onde, unsigned short* v ); Onde instrucao - a primeira mensagem, fica entre [ ] na tela mensagem - a segunda mensagem, que vai ficar antes do cursor tam - o tamanho maximo em bytes onde - endereco de onde vai montar o char[] com o retorno v - valor opcional, não precisa usar. Se usar, a função vai tentar converter para int o valor digitado e devolver ai, ou zero se não conseguir o valor de retorno é o endereço de onde :) Você chama assim por exemplo le_algo("ID: 1..999", "Entre ID a pesquisar: ", 3, valor, &id); E fica assim na tela [ID: 1..999] Entre ID a pesquisar: 5 E retorna valor = "5" e id=5, claro Eis um exemplo para a função. É bem simples e nem faz muitos testes, mas ao menos não cancela se o cara digitar letras ao invés de números. E trunca a saída se passar do tamanho. E converte pra int a ID no caso do seu exemplo char* le_algo( const char* instrucao, const char* mensagem, const unsigned short tam, char* onde, unsigned short* v ) { int i{}; int letra{}; cout << "[" << instrucao << "]\t" << mensagem << flush; letra = fgetc(stdin); // fim da linha anterior onde[0] = 0; do { letra = fgetc(stdin); if (letra == EOF) { onde[i] = 0; break; } if (letra == '\n') { onde[i] = 0; break; } onde[i] = letra; i += 1; } while (1); // le ate o fim da linha e termia a string if (v == NULL) return onde; // nao foi pedido o numero *v = 0; // vai precisar do numero for (i = 0; i < (int) strlen(onde); i += 1) { // se tem algo que nao seja numero retorna 0 if ((onde[i] < '0') || (onde[i] > '9')) return onde; } // end for // entao so tem numeros: converte *v = atoi(onde); return onde; } // end le_algo() Se vai ler uma string apenas pode usar a versão com menos parâmetros char* le_algo( const char* instrucao, const char* mensagem, const unsigned short tam, char* onde ) { // se nao vai ler um numero chama com NULL no final return le_algo(instrucao, mensagem, tam, onde, NULL); } // end le_algo() Pode te ajudar se não terminou ainda
  23. Felipe, você entendeu as duas declarações de Agenda que eu mostrei? Rodou o programa que eu te mostrei? Entendeu o gabarito que mostrei há pouco? Entendeu que não há como ter uma única agenda com aquela declaração e aquele enunciado? Entendeu a declaração de pessoa_fisica que eu te mostrei? template <typename TIPO, int MAX> struct Agenda { TIPO itens[MAX]; int quantidade; }; Como vai ler os valores é irrelevante. São 3 ou 4 campos apenas. Pode ler em uma função qualquer e passar um parâmetro como o formato: Lê uma string e grava como determinado. Note que isso é muito secundário aqui: não vi validar CNPJ, CPF ou telefone, não vai de fato cadastrar os nomes, não tem qualquer regra para o ID. Acho que foi a primeira coisa que eu recomendei: não perca tempo lendo valores do teclado. Faça o programa primeiro. adicionado 22 minutos depois Dois cafés depois: Se entendeu o que eu disse vai entender esse exemplo: Considerando a struct de pessoa fisica que te mostrei, imagine uma função que a cada vez que você chama ela devolve uma struct arrumadinha e única, e você chama a cada vez ao invés de se preocupar em como vai ler. Se você chama 15 vezes ela traz 15 structs para você inserir. Quando demora pra escrever isso? muito menos do que demora pra ficar digitando para dezenas de cin >> Uma rotina assim // // a cada vez que e chamada essa funcao retorna uma pessoa fisica assim // // celular "+55 12 9 1234 5XYZ" // CPF "012.345.67X-YZ" // ID XYZ // nome "nome XYZ" // // com XYZ a partir de 1 // Podia ser essa ve_ai_uma_pf() PF* ve_ai_uma_pf() { static unsigned short teste_id = 1; string prefixo_CPF{ "012.345.67" }; string prefixo_nome{ "nome " }; string prefixo_celular{ "+55 12 9 1234 5" }; char valor[20]; string um_valor; PF* nova_pf = new(PF); // cria uma nova struct PF para preencher // celular sprintf(valor, "%s%03d", prefixo_celular.c_str(), teste_id); um_valor = valor; nova_pf->celular = um_valor; // CPF sprintf(valor, "%s%d-%02d", prefixo_CPF.c_str(), (teste_id / 100), (teste_id % 100)); um_valor = valor; nova_pf->CPF = um_valor; // ID nova_pf->ID = teste_id; // nome sprintf(valor, "%s %03d", prefixo_nome.c_str(), teste_id); um_valor = valor; nova_pf->nome = um_valor; teste_id += 1; // incrementa para o proximo ficar diferente return nova_pf; }; // end ve_ai_uma_pf() Que mostra isso para 15 caras Testando leitura de dados para "pessoa fisica" Agenda Pessoal 1 012.345.670-01 'nome 001' +55 12 9 1234 5001 2 012.345.670-02 'nome 002' +55 12 9 1234 5002 3 012.345.670-03 'nome 003' +55 12 9 1234 5003 4 012.345.670-04 'nome 004' +55 12 9 1234 5004 5 012.345.670-05 'nome 005' +55 12 9 1234 5005 6 012.345.670-06 'nome 006' +55 12 9 1234 5006 7 012.345.670-07 'nome 007' +55 12 9 1234 5007 8 012.345.670-08 'nome 008' +55 12 9 1234 5008 9 012.345.670-09 'nome 009' +55 12 9 1234 5009 10 012.345.670-10 'nome 010' +55 12 9 1234 5010 11 012.345.670-11 'nome 011' +55 12 9 1234 5011 12 012.345.670-12 'nome 012' +55 12 9 1234 5012 13 012.345.670-13 'nome 013' +55 12 9 1234 5013 14 012.345.670-14 'nome 014' +55 12 9 1234 5014 15 012.345.670-15 'nome 015' +55 12 9 1234 5015 Chamando assim int testa_pf(int n) { PF* pessoa_fisica; cout << "Testando leitura de dados para \"pessoa fisica\"\n\n" << endl; cout << "Agenda Pessoal\n\n" << endl; for (int i = 0; i < n; i += 1) { pessoa_fisica = ve_ai_uma_pf(); cout << pessoa_fisica->ID << "\t" << pessoa_fisica->CPF << "\t'" << pessoa_fisica->nome << "'\t" << pessoa_fisica->celular << endl; } // end for return 0; } com testa_pf(15); Não tem nem 10 linhas cada função, e os campos vem todos numerados pra facilitar. Entende a diferença? Quando o programa estiver ok você troca essa ve_ai_uma_pf() por outra que le os 4 campos do teclado e pronto
  24. Pois é: como eu disse, estão em branco porque ainda não são necessárias. #pragma once é a versão do meu compilador para esses #ifndef / #define que você usa em seu compilador, que não sei qual é... Não, não é. A menos que você tenha trocado de enunciado e declarado a agenda de outro jeito. Você está com muita dúvida mas quer ajuda em uma única função? Você entendeu as declarações que te mostrei? Das agendas? Vai chegar um momento no programa em que vai ter que sair das templates e programar precisamente para a agenda em questão. As rotinas que inserem e mostram os dados. Brinde: um gabarito Muitas vezes é melhor usar um editor de texto e formatar mais ou menos como vai ser a saída. Veja esse possível exemplo para seu exercício. Tem uma régua com os números das colunas Agenda Pessoal ID CPF Nome Celular 1 2 3 4 5 6 7 ....5....0....5....0....5....0....5....0....5....0....5....0....5....0 000 012.345.67X-YZ nome +55 11 9 5678 1234 000 012.345.67X-YZ nome +55 11 9 5678 1234 000 012.345.67X-YZ nome +55 11 9 5678 1234 Agenda Comercial ID CNPJ Nome Celular 1 2 3 4 5 6 7 ....5....0....5....0....5....0....5....0....5....0....5....0....5....0 001 12.345.XYZ/000X-YZ EMPRESA XYZ +55 12 1234-5XYZ 001 12.345.XYZ/000X-YZ EMPRESA XYZ +55 12 1234-5XYZ 001 12.345.XYZ/000X-YZ EMPRESA XYZ +55 12 1234-5XYZ 001 12.345.XYZ/000X-YZ EMPRESA XYZ +55 12 1234-5XYZ 001 12.345.XYZ/000X-YZ EMPRESA XYZ +55 12 1234-5XYZ 001 12.345.XYZ/000X-YZ EMPRESA XYZ +55 12 1234-5XYZ 001 12.345.XYZ/000X-YZ EMPRESA XYZ +55 12 1234-5XYZ E um exemplo de uma struct que funciona para seu caso, podia ser um PF.h #include <iostream> using namespace std; struct PF { string celular; string CPF; unsigned short int ID; string nome; // o obvio, um parametro depois do outro, ordem alfabetica PF( string celular, string CPF, unsigned short int ID, string nome) : celular{ celular }, CPF{ CPF }, ID{ ID }, nome{ nome } {} PF() : ID{ 0 } {}; };
  25. Pensando melhor, talvez tenha sido injusto dizendo que é um exemplo ruim e que é praticamente C e não C++. Pode ser que o instrutor queira justamente começar assim e ir revendo o código até ficar mais próximo de um programa comum em C++. Mas já é outubro e logo acaba o período então talvez nem seja o caso. E usar templates nesse exemplo não foi mesmo uma boa ideia... Mas não dá pra discutir com um enunciado. Vamos ver até onde dá pra ir. Usando o que você já tinha digitado e mais uns 15' escrevi um esqueleto de um exemplo para você considerar. O exemplo mostra isso: [Usando Agenda Pessoal - 0 para alterar] 1. Inserir novo item no final da agenda 2. remover um item da agenda (pelo ID) 3. pesquisar um item na agenda (por ID ou nome) 4. mostrar todos os itens da agenda 5. encerrar o programa 6. Bonus: Ordena a agenda Opcao: E se teclar 0 passa para isso: [Usando Agenda Comercial - 0 para alterar] 1. Inserir novo item no final da agenda 2. remover um item da agenda (pelo ID) 3. pesquisar um item na agenda (por ID ou nome) 4. mostrar todos os itens da agenda 5. encerrar o programa 6. Bonus: Ordena a agenda Opcao: Bem óbvio. E se teclar 5 encerra. E a cada vez que tecla 0 o programa vai alterando entre as agendas como pedido.Está espelhando o enunciado. E as rotinas já estão declaradas. Pode ser um bom começo E já alterna entre as duas agendas como pedido. Veja o programa: #include <iostream> #include "PF.h" #include "PJ.h" #include "Agenda.h" using namespace std; int le_opcao() { int o; cout << "\nOpcao: "; cin >> o; return o; }; // end le_opcao() void mostra_menu(int* tipo) { if (*tipo == 0) { cout << "\n\n[Usando Agenda Pessoal - 0 para alterar]\n" << endl; } else { cout << "\n\n[Usando Agenda Comercial - 0 para alterar]\n" << endl; }; // end if cout << "1. Inserir novo item no final da agenda" << endl; cout << "2. remover um item da agenda (pelo ID)" << endl; cout << "3. pesquisar um item na agenda (por ID ou nome)" << endl; cout << "4. mostrar todos os itens da agenda" << endl; cout << "5. encerrar o programa" << endl; cout << "6. Bonus: Ordena a agenda" << endl; return; } int main() { int op = 0; int tipo_de_agenda = 0; // // faz o simples: mostra o menu, le a opcao, executa a opcao do { mostra_menu(&tipo_de_agenda); op = le_opcao(); switch (op) { case 5: // fim da linha cout << "Encerrando..." << endl; return 0; case 0: // muda o tipo de agenda if (tipo_de_agenda == 0) tipo_de_agenda = 1; else tipo_de_agenda = 0; break; } } while (op != 5); } E o header Agenda.h já tem as funções declaradas usando as tais templates: #pragma once #include <iostream> using namespace std; template <typename TIPO, int MAX> struct Agenda { TIPO itens[MAX]; int quantidade; }; template <typename TIPO, int MAX> bool inicializa_agenda(Agenda<TIPO, MAX>& agenda) { agenda.quantidade = 0; return true; } // end inicializa_agenda() template <typename TIPO, int MAX> bool inserir(TIPO entrada, Agenda<TIPO, MAX>& agenda) { return true; }; // end inserir() template <typename TIPO, int MAX> bool mostrar(Agenda<TIPO, MAX>& agenda) { return true; }; // end mostrar() template <typename TIPO, int MAX> bool pesquisar(int ID, Agenda<TIPO, MAX>& agenda) { return true; }; // end pesquisar(ID) template <typename TIPO, int MAX> bool pesquisar(string nome, Agenda<TIPO, MAX>& agenda) { return true; }; // end pesquisar(nome) template <typename TIPO, int MAX> bool remover(int ID, Agenda<TIPO, MAX>& agenda) { return true; }; // end remover() As outras estruturas para pessoa física e pessoa jurídica ainda estão em branco porque ainda não são necessárias TEMPLATES em ação: veja como declarar as agendas por exemplo: const int PESSOAL{ 0 }; const int COMERCIAL{ 1 }; int op = 0; int tipo_de_agenda = PESSOAL; Agenda<PF, 200> pessoal; inicializa_agenda <PF, 200>(pessoal); Agenda<PJ, 200> comercial; inicializa_agenda <PJ, 200>(comercial); Isso cria e inicializa as duas agendas, com um máximo de 200 itens em cada uma. E inicializa, que é uma coisa estranha em C++. Repito, esse é um exemplo bem ruim Quando tiver um tempo vou acrescentar algum código para o resto. Sugiro rodar esse programa em sua máquina. Tem interesse de fato no que estou explicando?

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!