Ir ao conteúdo
  • Cadastre-se
Maicon Dall Agnol

Problema com string em arquivos

Recommended Posts

Estou tendo dificuldades com a leitura e escrita de string em C. Tenho um trabalho que necessito fazer um cadastro de um número indefinido de pessoas (tipo uma agenda) em que deve ser cadastrado nome, telefone,etc..e como em arquivo existe as funções de strings que leem uma linha até a quebra de linha, eu faço a pessoa digitar os dados e no final de cada coisa eu acrescento um "\n"...Mas, quando vou recuperar esses arquivos para a leitura, como era de se esperar o ultimo contato cadastrado possui um "\n" sobrando, e na hora de mostrar ele acaba sendo um problema que acaba duplicando o ultimo contato...Então gostaria de saber se existe outra forma em melhor de agrupar esses dados para leitura e gravação pois dessa forma não estou encontrando uma solução para este problema.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não entendi direito, você salva e dps adiciona um enter?

E se adicionar um enter antes de cada contato em vez de depois?

Daí na hora da leitura você le o enter e os dados do contato até que chegue no EOF ou simplesmente até o tamanho total do arquivo.

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Eu recebo o dado que a pessoa digita, concateno ele com um "\n" e depois coloco no arquivo...E cheguei a fazer desse modo que disse colocando o "\n" antes do nome ficando assim \nMaicon por exemplo só que existe um problema..Quando o programa joga pra dentro do arquivo ele vai se organizar assim:

Citação

 

\n

Maicon\n

Luiz\n

Claudio\n

Pedro

 

 

Só que minha agenda tem diversas funções como exemplo, mostrar todos os contatos, mostrar todos os dados de um contato buscado, e a função excluir com contato, sendo que nesta acaba causando problema. Quando vou excluir um contato do meio ou do começo ele apenas exclui normalmente (estou fazendo a exclusão copiando todas linhas que não tem o nome do contato), mas o problema fica se eu excluir o ultimo contato, pois após a exclusão o penúltimo nome guarda o \n ficando assim:
 

Citação

 

\n

Maicon\n

Luiz\n

Claudio\n

 

 

o que acaba voltando para o problema anterior de sobrar um \n no final do arquivo, causando o problema de duplicação.

 

Eu até pensei um modo de corrigir isso que  seria apagando o ultimo \n após a exclusão do ultimo nome,  mas não consegui uma forma de apagar apenas ele.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não entendi como o \n extra no final causa o problema da duplicação, seria necessário ver o código para entender o que está acontecendo...

Compartilhar este post


Link para o post
Compartilhar em outros sites
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <locale.h>
#include <stdlib.h>

typedef struct Pessoa
{
	char nome[255],telefone[12];	
}pessoa;

//FUNÇÕES
void fun_cad(FILE *arq);
void fun_menu(FILE *arq);
void fun_mostra(FILE *arq);
void fun_exclui(FILE *arq);

int main(int argc, char const *argv[])
{
	FILE *arq;
	arq= fopen("contatos.txt","a+");
	setlocale(LC_ALL,"");
	fun_menu(arq);
  	fclose(arq);
}

void fun_menu(FILE *arq)
{
	int op;

	do
	{
		do
		{
			system("cls");
			printf("1-Cadastro\n");
			printf("2-Mostrar\n");
			printf("3-Excluir\n");
          	printf("0-Sair\n");
			printf("OPÇÃO: ");
			scanf("%d",&op);
		}while(op<0);

		switch(op)
		{
			case 1:
				fun_cad(arq);
			break;

			case 2:
				fun_mostra(arq);
			break;

			case 3:
				fun_exclui(arq);
			break;
		}	
	}while(op!=0);

}


void fun_cad(FILE *arq)
{
	int op;
	pessoa cad;
	char aux[2]="\n";

	printf("Nome: ");
	fflush(stdin);
	gets(cad.nome);

	printf("Telefone: ");
	fflush(stdin);
	gets(cad.telefone);

	printf("Deseja cadastrar o contato? \n");
	scanf("%d",&op);

	if(op==1)
	{
		strcat(aux,cad.nome);
		strcpy(cad.nome,aux);
		strcpy(aux,"\n");
		
		strcat(aux,cad.telefone);
		strcpy(cad.telefone,aux);
		strcpy(aux,"\n");
		
		fputs(cad.nome,arq);
		fputs(cad.telefone,arq);
	}

}

void fun_mostra(FILE *arq)
{
	rewind(arq);
	pessoa mos;
	char str[254];
	
	fgets(mos.nome,254,arq);
	system("cls");
	
	while(!feof(arq))
	{
		fgets(mos.nome,254,arq);
		printf("\t\tNome: ");
		puts(mos.nome);
		fgets(mos.telefone,254,arq);
		printf("\t\tTelefone: ");
		puts(mos.telefone);
		printf("----------------------------------------------\n");	
	}
	
	getch();
}

void fun_exclui(FILE *arq)
{
	int ver=0;
	char nome[255],cha;
	pessoa excl;
	FILE *aux=fopen("auxiliar.dat","w");
	rewind(arq);
	fgets(excl.nome,254,arq);
	fputs("\n",aux);
	
	system("cls");
	printf("Nome a ser excluido: ");
	fflush(stdin);
	gets(nome);
	strcat(nome,"\n");
	
	while(!feof(arq))
	{
		fgets(excl.nome,254,arq);
		fgets(excl.telefone,11,arq);
		
		if(strcmp(nome,excl.nome)==0)
			ver=1;
		else
		{
			fputs(excl.nome,aux);
			fputs(excl.telefone,aux);
		}
	}

	puts(excl.telefone);
	if(ver==1)
	{
		printf("CONTATO EXCLUIDO COM SUCESSO");
		fclose(arq);
		fclose(aux);
		
		remove("contatos.txt");
		rename("auxiliar.dat","contatos.txt");
		arq=fopen("contatos.txt","a+");
	}
	else 
	{
		printf("Contato não encontrado\n");	
		fclose(aux);
		remove("auxiliar.dat");
	}
	
	fclose(aux);
	
	getch();
	
}

Esse é o código que foi mais funcional que é colocando o \n antes do nome mas causa o problema da mesma forma..Tenta compilar e executar, ai cadastra 2 contatos e depois excluir o segundo, no caso o ultimo contato, que vai ver o problema quando for mostrar os nomes e telefones

Compartilhar este post


Link para o post
Compartilhar em outros sites

Aqui acredito que isto resolva o seu problema:

 

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <locale.h>
#include <stdlib.h>

typedef struct Pessoa
{
	char nome[255],telefone[12];	
}pessoa;

//FUNÇÕES
void fun_cad(FILE *arq);
void fun_menu(FILE *arq);
void fun_mostra(FILE *arq);
void fun_exclui(FILE *arq);

int main(int argc, char const *argv[])
{
	FILE *arq;
	arq= fopen("contatos.txt","a+");
	setlocale(LC_ALL,"");
	fun_menu(arq);
  	fclose(arq);
}

void fun_menu(FILE *arq)
{
	int op;

	do
	{
		do
		{
			system("cls");
			printf("1-Cadastro\n");
			printf("2-Mostrar\n");
			printf("3-Excluir\n");
          	printf("0-Sair\n");
			printf("OPÇÃO: ");
			scanf("%d",&op);
		}while(op<0);

		switch(op)
		{
			case 1:
				fun_cad(arq);
			break;

			case 2:
				fun_mostra(arq);
			break;

			case 3:
				fun_exclui(arq);
			break;
		}	
	}while(op!=0);

}


void fun_cad(FILE *arq)
{
	int op;
	pessoa cad;
	char aux[2]="\n";

	printf("Nome: ");
	fflush(stdin);
	gets(cad.nome);

	printf("Telefone: ");
	fflush(stdin);
	gets(cad.telefone);

	printf("Deseja cadastrar o contato? \n");
	scanf("%d",&op);

	if(op==1)
	{
		strcat(cad.nome,aux);
		
		strcat(cad.telefone,aux);
		
		fputs(cad.nome,arq);
		fputs(cad.telefone,arq);
	}

}

void fun_mostra(FILE *arq)
{
	rewind(arq);
	pessoa mos;
	char aux[2]="\n";
	
	system("cls");
	
	fgets(mos.nome,254,arq);
	while(!feof(arq) && strcmp(mos.nome,aux) != 0)
	{
		printf("\t\tNome: ");
		puts(mos.nome);
		fgets(mos.telefone,254,arq);
		printf("\t\tTelefone: ");
		puts(mos.telefone);
		printf("----------------------------------------------\n");	
		fgets(mos.nome,254,arq);
	}
	
	getch();
}

void fun_exclui(FILE *arq)
{
	int ver=0;
	char nome[255],cha[2]="\n";
	pessoa excl;
	FILE *aux=fopen("auxiliar.dat","w");
	rewind(arq);
	
	system("cls");
	printf("Nome a ser excluido: ");
	fflush(stdin);
	gets(nome);
	strcat(nome,"\n");
	
	fgets(excl.nome,254,arq);
	while(!feof(arq) && strcmp(excl.nome,cha) != 0)
	{
		fgets(excl.telefone,11,arq);
		
		if(strcmp(nome,excl.nome)==0)
			ver=1;
		else
		{
			fputs(excl.nome,aux);
			fputs(excl.telefone,aux);
		}
		fgets(excl.nome,254,arq);
	}

	if(ver==1)
	{
		printf("CONTATO EXCLUIDO COM SUCESSO");
		fclose(arq);
		fclose(aux);
		
		remove("contatos.txt");
		rename("auxiliar.dat","contatos.txt");
		arq=fopen("contatos.txt","a+");
	}
	else 
	{
		printf("Contato não encontrado\n");	
		fclose(aux);
		remove("auxiliar.dat");
	}
	
	fclose(aux);
	
	getch();
	
}

Agora não importa que o "\n" está no final do arquivo, pois tanto a fun_mostra quanto a fun_exclui checam ambos, se o arquivo chegou ao fim, e se mos.nome e excl.nome têm algum nome armazenado antes executar o loop (com um fgets antes de entrar no loop, e no fim de cada loop).

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Eu tentei usar seu programa mas ele não esta cadastrando os contatos, e nem mostrando os que ja estavam cadastrados. Até entendi o que você quis fazer mas assim como os outros erros também não entendi o motivo do erro

Compartilhar este post


Link para o post
Compartilhar em outros sites
17 minutos atrás, Maicon Dall Agnol disse:

Eu tentei usar seu programa mas ele não esta cadastrando os contatos, e nem mostrando os que ja estavam cadastrados. Até entendi o que você quis fazer mas assim como os outros erros também não entendi o motivo do erro

O problema provavelmente é que o arquivo que você já tem dados cadastrados tem o caractere nova linha ("\n") no começo. Se você deseja mantê-lo ao invés de recomeçar o cadastro basta remover manualmente a linha em branco no começo do arquivo e salvar.

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
1 hora atrás, isrnick disse:

O problema provavelmente é que o arquivo que você já tem dados cadastrados tem o caractere nova linha ("\n") no começo. Se você deseja mantê-lo ao invés de recomeçar o cadastro basta remover manualmente a linha em branco no começo do arquivo e salvar.

 

Era essa mesmo hahahah, eu estava com a lista já salva, assim ele não chegava a entrar no while por causa da verificação inicial...Mas agora está funcionando perfeitamente!!Alem disso essa verificação anterior vai me servir em outros aspectos pois é um projeto de uma agenda bem completa, é um trabalho de faculdade que tive que fazer a agenda em vetor, depois modifica-lá para alocação dinâmica e agora era em arquivos..então vai ter bem mais funções e dados cadastrados como endereço,aniversario,outros números de telefone,etc..E essa verificação vai me ajudar a mostrar se a lista está vazia deixando ela visualmente melhor! Esse era o protótipo para agora eu começar a implementar no principal (Agora é que vai vir os bugs mesmos)..Mas muitíssimo obrigado pela ajuda, realmente me salvou!

  • Curtir 1

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

×