Ir ao conteúdo
  • Cadastre-se
Felipe.Oliveira9

Salvar e abrir struct em arquivo.csv no c

Recommended Posts

Boa tarde.
Estou tendo dificuldades com um trabalho em C.


O professor pediu para que o programa aceitasse a inclusão e impressão de struct na tela: OK

O professor também quer que o programa salve as entidades armazenadas na struct em arquivo para que os dados não sejam perdidos quando o programa for fechado e quer que esses dados sejam carregados depois no programa. Não estou conseguindo fazer funcionar essa parte de gravação e abertura dos dados no arquivo.

O programa simplesmente está replicando os dados digitados pela primeira vez ao invés de exibir os dados separados quando eu imprimo na tela, um para cada posição da struct.

Desde já agradeço a ajuda.

Código:

 

#include <stdio.h>
#include <string.h>

struct T_livro {
	int isbn;
	char nome[200];
	char autor[200];
	char idioma[30];
	int idade;
};

struct T_livro livros[1000];
int contador = -1;

int lerInteiro(char mensagem[]) {
	int numero;
	printf(mensagem);
	scanf("%d", &numero);
	fflush(stdin); // limpar no buffer do teclado o caracter Enter anterior 
	return numero;
}

void lerString(char mensagem[], char leitura[]) {
	printf(mensagem);
	gets(leitura);
}

void lerLivro(struct T_livro *pLivro) {
	system("cls");
	printf("\nDigite o codigo ISBN do Livro: ");
	scanf("%d", &pLivro->isbn);
	fflush(stdin);

	printf("\nDigite o nome do livro: ");
	gets(pLivro->nome);
	
	printf("\nDigite o nome do autor: ");
	gets(pLivro->autor);
	
	printf("\nDigite o idioma do livro: ");
	gets(pLivro->idioma);
	
	printf("\nDigite a idade recomendada: ");
	scanf("%d", &pLivro->idade);
	fflush(stdin);
}

void imprimirLivro(struct T_livro livro) {
	printf("\nNome: %s - ISBN: %d", livro.nome, livro.isbn);
	printf("\nAutor: %s", livro.autor);
	printf("\nIdioma: %s", livro.idioma);
	printf("\nIdade: %d", livro.idade);
	printf("\n");
}

int mostrarMenu() {
	int escolha;
	system("cls");
	printf("\n***************************************");
	printf("\n** MENU DE opções");
	printf("\n** 0 - Sair");
	printf("\n** 1 - Incluir um livro");
	printf("\n** 2 - Imprimir todos os livros");
	printf("\n** 3 - Salvar livros");
	printf("\n** 4 - Carregar livros");
	printf("\n***************************************");
	printf("\nDigite uma opcao: ");
	scanf("%d", &escolha);
	fflush(stdin); // limpar no buffer do teclado o caracter Enter anterior 
	
	return escolha;
}

void incluirLivro() {
	contador++;
	lerLivro( &livros[contador] );
}

void imprimirTodos() {
	system("cls");
	int i;
	for (i=0; i<=contador; i++)
		imprimirLivro( livros[i] );
}

void gravarLivros() {
	FILE *arquivo = fopen("livros.csv","w");
	
	// IMPRIMIR O CABECALHO DO ARQUIVO
	//fprintf(arquivo, "ISBN;NOME;AUTOR;IDIOMA;IDADE\n");
	
	int i;
	for (i=0; i<=contador; i++) {
		fprintf(arquivo, "%d;", livros[contador].isbn );
		fprintf(arquivo, "%s;", livros[contador].nome );
		fprintf(arquivo, "%s;", livros[contador].autor );
		fprintf(arquivo, "%s;", livros[contador].idioma );
		fprintf(arquivo, "%d;", livros[contador].idade );		
		fprintf(arquivo, "\n" );
	}
	
	fclose(arquivo);
} 

void lerLivros()
{
	FILE *arquivo = fopen("livros.csv","r");
	
	if (arquivo == NULL)
	{
		printf("Arquivo nao encontrado ou acesso negado pelo SO.");
	}
	else
	{
		contador = -1;
		
		// EXECUTA ENQUANTO NÃO FOR FIM DE ARQUIVO (EOF - end of file)
		while ( !feof(arquivo) ) 
		{
			contador++;
			fscanf(arquivo, "%d;", &livros[contador].isbn);
			fscanf(arquivo, "%[^;]%*c", &livros[contador].nome);
			fscanf(arquivo, "%[^;]%*c", &livros[contador].autor);
			fscanf(arquivo, "%[^;]%*c", &livros[contador].idioma);
			fscanf(arquivo, "%d;", &livros[contador].idade);
		}
	
		// TESTE IMPRINDO OS ALUNOS LIDOS PARA VERIFICAR
		imprimirTodos();
		
		fclose(arquivo);
	}
	
} 



void main() {

	int opcao;
	do
	{
		opcao = mostrarMenu();
		
		switch(opcao)
		{
			case 0:
				printf("\nAte mais!");
				break;
				
			case 1:
				incluirLivro();
				break;
	
			case 2:
				imprimirTodos();
				break;
	
			case 3:
				gravarLivros();
				break;
	
			case 4:
				lerLivros();
				break;

			default:
				printf("\nOpcao invalida!");
				break;
		}
		printf("\n\nPressione qualquer tecla...");
		getch();
			
	}
	while(opcao != 0);

}

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Na função gravarLivros() a variável sendo incrementada de 0 até contador é a variável i, logo é a variável i que deve ser colocada entre os colchetes da struct livros:

 

void gravarLivros() {
	FILE *arquivo = fopen("livros.csv","w");
	
	// IMPRIMIR O CABECALHO DO ARQUIVO
	//fprintf(arquivo, "ISBN;NOME;AUTOR;IDIOMA;IDADE\n");
	
	int i;
	for (i=0; i<=contador; i++) {
		fprintf(arquivo, "%d;", livros[i].isbn );
		fprintf(arquivo, "%s;", livros[i].nome );
		fprintf(arquivo, "%s;", livros[i].autor );
		fprintf(arquivo, "%s;", livros[i].idioma );
		fprintf(arquivo, "%d;", livros[i].idade );		
		fprintf(arquivo, "\n" );
	}
	
	fclose(arquivo);
} 

 

E provavelmente seja mais interessante sempre salvar cada livro automaticamente no arquivo "livros.csv" assim que ele é adicionado, e sempre carregar os livros automaticamente toda vez que o programa for executado (se o arquivo "livros.csv" existir), ao invés de fazer isso apenas quando o usuário solicitar.

 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@isrnick Entendi, vou tentar fazer dessa forma. 

Foi o professor que pediu um menu para salvar e carregar.

 

Como eu faria para ele fazer isso automaticamente? Eu poderia continuar com o menu fazendo isso?

 

Como eu faço para excluir (o professor disse que só vamos aprender a excluir em estrura de Dados, mas eu fiquei curioso)

 

Ps: não sou muito bom em programação, essa matéria de arquivos tivemos na aula passada e foi meio rápido.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa noite.

Fiz as alterações mas o programa continua dando erro.

Compartilhar este post


Link para o post
Compartilhar em outros sites
3 horas atrás, Felipe.Oliveira9 disse:

Como eu faria para ele fazer isso automaticamente? Eu poderia continuar com o menu fazendo isso?

 

Simplesmente chamar a função lerLivros() no Main do programa antes de entrar no ciclo "do while" já carregaria automaticamente os dados salvos no arquivo para a memória.

 

E na função incluirLivro() bastaria abrir o arquivo no modo de anexação de dados ao final do arquivo (usando o parâmetro "a" ao invés de "w"), e salvar os valores no arquivo imediatamente após obtê-los.

 

3 horas atrás, Felipe.Oliveira9 disse:

Como eu faço para excluir (o professor disse que só vamos aprender a excluir em estrura de Dados, mas eu fiquei curioso)

 

Existem varias maneiras, uma simples no seu caso seria fazer uma função que gravasse tudo novamente no arquivo "livros.csv" exceto os dados do livro correspondente identificado para ser excluído, e então basta usar a função para carregar os livros novamente e a struct livros seria atualizada sem o respectivo livro.

 

 

 

1 hora atrás, Felipe.Oliveira9 disse:

Boa noite.

Fiz as alterações mas o programa continua dando erro.

#include <stdio.h>
#include <string.h>

struct T_livro {
	int isbn;
	char nome[200];
	char autor[200];
	char idioma[30];
	int idade;
};

struct T_livro livros[1000];
int contador = -1;

int lerInteiro(char mensagem[]) {
	int numero;
	printf(mensagem);
	scanf("%d", &numero);
	fflush(stdin); // limpar no buffer do teclado o caracter Enter anterior 
	return numero;
}

void lerString(char mensagem[], char leitura[]) {
	printf(mensagem);
	gets(leitura);
}

void lerLivro(struct T_livro *pLivro) {
	system("cls");
	printf("\nDigite o codigo ISBN do Livro: ");
	scanf("%d", &pLivro->isbn);
	fflush(stdin);

	printf("\nDigite o nome do livro: ");
	gets(pLivro->nome);
	
	printf("\nDigite o nome do autor: ");
	gets(pLivro->autor);
	
	printf("\nDigite o idioma do livro: ");
	gets(pLivro->idioma);
	
	printf("\nDigite a idade recomendada: ");
	scanf("%d", &pLivro->idade);
	fflush(stdin);
}

void imprimirLivro(struct T_livro livro) {
	printf("\nNome: %s - ISBN: %d", livro.nome, livro.isbn);
	printf("\nAutor: %s", livro.autor);
	printf("\nIdioma: %s", livro.idioma);
	printf("\nIdade: %d", livro.idade);
	printf("\n");
}

int mostrarMenu() {
	int escolha;
	system("cls");
	printf("\n***************************************");
	printf("\n** MENU DE opções");
	printf("\n** 0 - Sair");
	printf("\n** 1 - Incluir um livro");
	printf("\n** 2 - Imprimir todos os livros");
	printf("\n** 3 - Salvar livros");
	printf("\n** 4 - Carregar livros");
	printf("\n***************************************");
	printf("\nDigite uma opcao: ");
	scanf("%d", &escolha);
	fflush(stdin); // limpar no buffer do teclado o caracter Enter anterior 
	
	return escolha;
}

void incluirLivro() {
	contador++;
	lerLivro( &livros[contador] );
}

void imprimirTodos() {
	system("cls");
	int i;
	for (i=0; i<=contador; i++)
		imprimirLivro( livros[i] );
}

void gravarLivros() {
	FILE *arquivo = fopen("livros.csv","w");
	
	// IMPRIMIR O CABECALHO DO ARQUIVO
	//fprintf(arquivo, "ISBN;NOME;AUTOR;IDIOMA;IDADE\n");
	
	int i;
	for (i=0; i<=contador; i++) {
		fprintf(arquivo, "%d;", livros[i].isbn );
		fprintf(arquivo, "%s;", livros[i].nome );
		fprintf(arquivo, "%s;", livros[i].autor );
		fprintf(arquivo, "%s;", livros[i].idioma );
		fprintf(arquivo, "%d;", livros[i].idade );
		fprintf(arquivo, "\n" );
	}
	
	fclose(arquivo);
} 

void lerLivros()
{
	FILE *arquivo = fopen("livros.csv","r");
	
	if (arquivo == NULL)
	{
		printf("Arquivo nao encontrado ou acesso negado pelo SO.");
	}
	else
	{
		contador = -1;
		
		// EXECUTA ENQUANTO NÃO FOR FIM DE ARQUIVO (EOF - end of file)
		while ( !feof(arquivo) ) 
		{
			contador++;
			fscanf(arquivo, "%d;", &livros[contador].isbn);
			fscanf(arquivo, "%[^;]%*c", &livros[contador].nome);
			fscanf(arquivo, "%[^;]%*c", &livros[contador].autor);
			fscanf(arquivo, "%[^;]%*c", &livros[contador].idioma);
			fscanf(arquivo, "%d;\n", &livros[contador].idade);
		}
	
		// TESTE IMPRINDO OS ALUNOS LIDOS PARA VERIFICAR
		imprimirTodos();
		
		fclose(arquivo);
	}
	
} 



void main() {

	int opcao;
	do
	{
		opcao = mostrarMenu();
		
		switch(opcao)
		{
			case 0:
				printf("\nAte mais!");
				break;
				
			case 1:
				incluirLivro();
				break;
	
			case 2:
				imprimirTodos();
				break;
	
			case 3:
				gravarLivros();
				break;
	
			case 4:
				lerLivros();
				break;

			default:
				printf("\nOpcao invalida!");
				break;
		}
		printf("\n\nPressione qualquer tecla...");
		getch();
			
	}
	while(opcao != 0);

}

Além da alteração que eu mencionei no meu post anterior a única coisa que fiz foi adicionar um '\n' no último fscanf da função lerLivros() para que o programa não interprete a última linha em branco do arquivo como sendo um livro a ser lido... Desta maneira o programa alcança o fim do arquivo e não executa novamente o ciclo while.

 

Se tiver mais algum problema é só postar.

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@isrnick Caraca, funcionou, nem acredito.

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

×