Ir ao conteúdo
  • Cadastre-se
vitao1020

C Erro em código de programação C

Posts recomendados

Gostaria de uma ajuda em relação a um código que fiz de uma agenda de contatos com funções de criar, alterar, salvar, excluir e modificar. Consegui adicionar as funções exceto a de salvar e modificar na qual já tentei de tudo e não obtive exito, alguém sabe o que preciso pra fazer essas funções funcionarem ou adicionar elas?

	#include <stdio.h>
	

	typedef struct
    {
	int codigo;
	char nome[10];
	char end[30];
	char tel[10];
	int ativo;
	}Agenda;
	
void cabecalho (char *titulo){
	system("cls");
	printf("\n\n--==[%s]==--\n\n", titulo);
}
	main()
	{
	FILE *arq;
	Agenda pessoa;
	int opcao, pos;
	char resp;
	
	arq = fopen ("Agenda.dat", "a+b");
	if(arq == NULL)
		printf("Erro ao tentar abrir o arquivo.");
	else{
		do{
		cabecalho("Menu Principal");
		printf("1 - Cadastrar pessoa \n");
		printf("2 - Alterar pessoa \n");
		printf("3 - Excluir pessoa \n");
		printf("4 - Consultar pessoa \n");
		printf("5 - Listar \n");
		printf("6 - Sair \n");  
		scanf("%d", &opcao);
        getchar();
		
		switch(opcao){
		
		case 1:
			cabecalho("Cadastrar Pessoa");
			pessoa.ativo = 1;
			printf("Digite o codigo: \n");
            scanf("%d", &pessoa.codigo);
			fflush(stdin);
			printf("Digite o nome:\n");
			gets(pessoa.nome);
			fflush(stdin);
			printf("Digite o endereco:\n");
			gets(pessoa.end);
			fflush(stdin);
			printf("Digite o telefone:\n");
			gets(pessoa.tel);
			fflush(stdin);
			
			fwrite(&pessoa, sizeof(pessoa),1, arq);
			
			if(ferror(arq))
				printf("Erro na gravação do arquivo.");
			else
				printf("Cliente cadastrado com sucesso.");
			break;
		case 2:
			cabecalho("Alterar Pessoa");
			printf("Digite a codigo do cliente que deseja alterar.");
			scanf("%d", &pos);
			getchar();
			
			fseek(arq, sizeof(Agenda)*(pos - 1), SEEK_SET);
			
			if (ferror(arq))
				printf("Erro no posicionamento do cursor.");
			else{
				fread(&pessoa, sizeof(Agenda), 1, arq);
				
				if(ferror(arq))
					printf("\nErro na leitura do arquivo");
				else{
					printf("\nCodigo do cliente: %d", pessoa.codigo);
					printf("\nNome do cliente: %s", pessoa.nome);
					printf("\nEndereco do cliente: %s", pessoa.end);
					printf("\nTelefone do cliente: %s", pessoa.tel);				
				}
			}
			printf("\nDigite o novo codigo do cliente:");
			scanf("%d", &pessoa.codigo);
			getchar();
			printf("\nDigite o novo nome do cliente:");
			gets(pessoa.nome);			
			printf("\nDigite o novo endereco do cliente:");
			gets(pessoa.end);
			printf("\nDigite o novo telefone do cliente:");
			gets(pessoa.tel);
			
			fseek(arq, sizeof(Agenda)*(pos - 1), SEEK_SET);
			fwrite(&pessoa, sizeof(Agenda),1,arq);
			break;
		case 3:
			cabecalho("Excluir pessoa");
			printf("Digite o codigo que desejar excluir");
			scanf("%d",&pos);
			getchar();
	
			fseek(arq, sizeof(Agenda)*(pos - 1), SEEK_SET);
			if(ferror(arq))
			printf("Erro no posionamento do cursor.");
			else{
			fread(&pessoa, sizeof(Agenda), 1, arq);
			
			if(ferror(arq))
				printf("Erro na leitura do arquivo.");
			else{
				printf("\nCliente codigo: %d", pessoa.codigo);
				printf("\nCliente nome: %s", pessoa.nome);
				printf("\nCliente endereco: %s", pessoa.end);
				printf("\nCliente telefone: %s", pessoa.tel);
				printf("\nCliente ativo: %d", pessoa.ativo);
			}
		}
	
		do{
			printf("\nConfirma exclusao? (s/n)");
			resp = towlower(getchar());
		}while (resp != 's' && resp != 'n' );
		
		if(resp == 's'){
			fseek(arq, sizeof(Agenda)*(pos - 1), SEEK_SET);
			
			pessoa.ativo = 0;
			
			fwrite(&pessoa, sizeof(Agenda), 1, arq);
			
			if(ferror(arq))
				printf("Erro na exclusao do registro");
			else
				printf("exclusao efetuada com sucesso");
			
		}else printf("exclusao nao efetuada");
		break;
		case 4:

			cabecalho("Consultar pessoa");
			printf("\n Digite o codigo que deseja consultar: ");
			scanf("%d",&pos);
			getchar();
			
			fseek(arq, sizeof(Agenda)*(pos - 1), SEEK_SET);
			if(ferror(arq))
			    printf("\nErro no posicionamento do cursor");
			else{
				fread(&pessoa, sizeof(Agenda), 1, arq);
				
				if(ferror(arq))
					printf("\nErro na leitura do registro");
			else{
				printf("\nCliente codigo: %d", pessoa.codigo);
				printf("\nCliente nome: %s", pessoa.nome);
				printf("\nCliente endereco: %s", pessoa.end);
				printf("\nCliente telefone: %s", pessoa.tel);
	   	   	}
		}
		getchar();
	
		break;
		case 5:
		
			cabecalho("Listar");
			rewind(arq);
			if(ferror(arq))
				printf("\nErro no posicionamento do cursor");
			else{
				while(!feof(arq)){
					fread(&pessoa, sizeof(Agenda), 1, arq);
					
					if(ferror(arq))
						printf("\nErro na leitura do registro");
			else{
				if (!feof(arq)){
				if(pessoa.ativo){
					printf("\nCliente codigo: %d", pessoa.codigo);
					printf("\nCliente nome: %s", pessoa.nome);
					printf("\nCliente endereco: %s", pessoa.end);
					printf("\nCliente telefone: %s\n", pessoa.tel);
					printf("\nCliente ativo: %d\n", pessoa.ativo);
					
				}
			}
		}
	}
}
		getchar();
		
		   }
		  }while(opcao !=6);
		 
		
	}
	fclose(arq);
	return 0;
	}

		

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá!
 

Sua intenção é gravar em posições fixas no arquivo a partir do código de cada entrada? Como é o controle disso? 

O arquivo é uma sequência de registros de Agenda, mas como vai controlar o espaço em uso?

Não sei se entendi.
Nessas implementações com simples arquivos em geral se grava as entradas uma após a outra mesmo e depois a cada acesso vai varrendo os registros, ou se formata o arquivo com as células vazias para a capacidade total prevista, antes de começar a usar mesmo. Uma função cria o arquivo com um certo número de entradas

Compartilhar este post


Link para o post
Compartilhar em outros sites

@arfneto Eu quero gravar dessa maneira e poder alterar um registro na posição especifica do ponteiro, que é tô querendo é colocar o ponteiro em um registro especifico, estou usando struct pra pode fazer o arquivo, porque pra fazer modificação eu quero alterar e salvar arquivos especificos

Compartilhar este post


Link para o post
Compartilhar em outros sites
2 horas atrás, vitao1020 disse:

e poder alterar um registro na posição especifica do ponteiro, que é tô querendo é colocar o ponteiro em um registro especifico, estou usando struct pra pode fazer o arquivo, porque pra fazer modificação eu quero alterar e salvar arquivos especificos

 

Achei um pouco confuso isso que escreveu :(

 

Talvez fseek, fwrite e os métodos de manipulação de arquivos não funcionem do modo como você pensa.

 

Veja esse trecho do manual: 

 

Citação

Quando um arquivo é aberto para acrescentar dados, a posição do arquivo atual é determinada pela última operação de E/S e não por onde a gravação seguinte ocorreria. Se nenhuma operação de E/S tiver ocorrido em um arquivo aberto para acréscimo, a posição do arquivo será o início do arquivo

 

Isso na documentação da Microsoft

 

Ou seja, não abra em append mode. Use "wb". Mas entenda que como você usa o arquivo também pra ler vai ter que ir mudando os modos conforme a opção do usuário...

 

Veja a saída 

 

190604-saidaprograma.png.bf4694835ef1827f5e03c954eda0e5c8.png

 

Deste programa

 

int main(int argc,	char **argv)
{
	typedef struct
	{
		int codigo;
		char nome[10];
		char end[30];
		char tel[10];
		int ativo;
	} Item;

	char * nome = "agenda.dat";
	FILE * agenda;
	long r;
	int item_size = sizeof(Item);
	Item item;

	agenda = fopen(nome, "wb");
	if (agenda == NULL)
	{
		printf("Erro ao tentar abrir %s\n", nome);
		exit(-1);
	}
	printf("Aberto %s\n", nome);
	printf("size of item: %d\n", sizeof(Item));
	r = fseek(agenda, (1000 * item_size), SEEK_SET);
	if (r != 0)
	{
		printf("Erro: %s\n", errno);
		exit(-2);
	}
	printf("fseek posicionou com sucesso o ponteiro no registro 1000\n");
	// prepara um registro de teste
	item.codigo = 1000;
	strcpy(item.nome, "Nome1000");
	strcpy(item.end, "End1000");
	strcpy(item.tel, "Tel1000");
	item.ativo = 1;

	r = fwrite(&item, item_size, 1, agenda);
	printf("Gravados %d items com %d bytes cada\n", r, item_size);
	r = fclose(agenda);
	struct stat fileInfo;
	r = stat(nome, &fileInfo);
	printf("Arquivo '%s' tem %d bytes\n", nome, fileInfo.st_size);
}	// end main

E abaixo o final do arquivo

 

19004-dump.thumb.png.b08880f106cdcf749652a9041ca16b00.png

 

Note que EA60 em hexadecimal é .... 60.000, como esperado, já que gravou o registro na posição 1000 e o primeiro registro é 0 então o SEEK funcionou ok...

Que ambiente usa para escrever seus programas? sistema, compilador, essas coisas?

 

Abraço

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

@arfneto ainda tô aprendendo o básico sobre programação C, uso o falcou ou o dev. Não aprendi ainda sobre hexadecimal, queria saber se com esse código que fiz o que preciso fazer para que a função de alterar e salvar funcione pois são as únicas coisas que estão faltando

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá!

 

Você leu o que escrevi? 

Leu o programa que deixei no tópico?

 

Não sei o que são falcon ou dev. Onde tem isso? Em que sistema roda?

 

Hexadecimal é importante você saber se está criando arquivos no disco e quer ver lá no disco o que foi gravado, em especial quando usa arquivos em binário como em seu programa. No entanto, bases de numeração, como binário, hexadecimal e decimal, fazem parte do CURRÍCULO DE MATEMÁTICA PARA O ENSINO FUNDAMENTAL, como esse descrito aqui para PE por exemplo. Não está previsto eu acho ensinar isso em programação C. Mas é igualzinho o decimal, apenas cada posição no número pode ter 2 dígitos em binário, 8 em octal, 16 em hexadecimal e assim vai. Só isso.

 

Ex: EA60 como eu disse. Hexadecimal usa 16 "dígitos" então como só temos 10 números porque usamos decimal em geral, são usadas letras A B C D E F para compor o resto e então os dígitos vão de 0 a 9 depois ABCDEF, e obviamente nessa ordem o A vale 10, o B 11 e o F 15... assim voltando ao número EA60,

  • 0 é zero mesmo
  • 6 vale 16 x 6 = 96
  • A vale 10 x 16 x 16 = 2560
  • E vale 14 * 16 * 16 * 16 = 57344

E a soma, como já vimos, é 60.000 o que significa que o seek funcionou direitinho

 

Compare com o número 128 em decimal

  • 8 vale 8 mesmo
  • 2 vale 2 x 10 = 20
  • 1 vale 1 * 10 * 10 = 100

E a soma, com se sabe, é 128. Caddígito mais a esquerda multiplica pela base, cero? 1, 10, 100, 1000.. 

 

Sobre o ambiente em que programa, pergunto porque alguns ambientes rodam seu programa direto do editor, mostram a sintaxe, consultam o manual direto, escrevem os comandos com cores... Então fica mais fácil progredir e aprender, muito embora tenha instrutores que prefiram um mínimo desses mimos modernos...

 

Uso Windows 10, a calculadora do Windows calcula em hexadecimal e converte quando precisa, tem por exemplo o ambiente Visual Studio que não é bem para C mas funciona ok com C e você pode por exemplo ver as declarações das funções direto na tela ao apontar com o mouse para a linha do programa, por exemplo. E selecionar a função e apertar F1 leva você direto pro manual (online)...

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

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

Crie uma nova conta

Entrar

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

Entrar agora





Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações 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...

GRÁTIS: minicurso “Como ganhar dinheiro montando computadores”

Gabriel TorresGabriel Torres, fundador e editor executivo do Clube do Hardware, acaba de lançar um minicurso totalmente gratuito: "Como ganhar dinheiro montando computadores".

Você aprenderá sobre o quanto pode ganhar, como cobrar, como lidar com a concorrência, como se tornar um profissional altamente qualificado e muito mais!

Inscreva-se agora!