Ir ao conteúdo

Posts recomendados

Postado

Boa tarde,

 

Estou fazendo um trabalho da faculdade, usando arquivo, no qual o usuário realiza cadastros de livros e operações básicas como listar, alterar, excluir etc

No entanto, estou com dificuldades na função visualizar para fazer com que meu programa liste todos os livros cadastrados. Ele mostra apenas o ultimo.

Podem ter algumas coisas erradas no código em geral, eu meio que to fazendo e aprendendo ao mesmo tempo, se alguém conseguir dar uma dica ou mostrar como ficaria essa parte, agradeço.

Segue o código:

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#define TAM 100


FILE *pArq; 

typedef struct biblioteca {
    char nome_livro[500], autor[500], livro_lido[500];
    int pags, num_livro;
}cad;
cad lib[TAM];


void cadastrar(); 
void visualizar(); 

int main()
{
    setlocale(LC_ALL, "Portuguese");
	int i, opcao, cont;
  
    i = opcao = cont = 0;

     while (opcao != 6) {
  
        printf("\n\n--------------"
               " BEM-VINDO A SUA BIBLIOTECA "
               "----------------\n");
        printf("\n\n *Utilize os números para navegar no menu* \n");
        printf("\n\n-------------------------\n");
        printf("1. ADICIONAR UM LIVRO NOVO\n ");
        printf("2. MOSTRAR LIVROS CADASTRADOS\n");
        printf("6. SAIR");  

        printf("\n\nESCOLHA UMA DAS opções ACIMA: ");
        scanf("%d", &opcao);
  
        
        switch (opcao) {
  
         
        case 1:
  
            cadastrar();
            system ("pause");
            break;
        
        case 2:
            visualizar();
            break;
        
        case 6:
            exit(0);
        }
    }
	getchar();
	return 0;
}

void abrir_arq(){
	pArq = fopen("biblioteca.txt", "a");
    if(pArq == NULL){
    printf("Erro na abertura do arquivo!");
    return 1;  
    }
return 0;
}

void cadastrar()
{
    int i;
    int cont;
    abrir_arq("a");

	for(i=0;i<1;i++)
	{
        getchar();
        printf("INSIRA O NÚMERO DO LIVRO: ");
        scanf("%d", &lib[i].num_livro);
        
           
        printf("INSIRA O NOME DO LIVRO: ");
        scanf("%s", &lib[i].nome_livro);
        
  
        printf("INSIRA O NOME DO AUTOR: ");
        scanf("%s", &lib[i].autor);
        
  
        printf("INSIRA O NÚMERO DE PÁGINAS: ");
        scanf("%d", &lib[i].pags);
        
  
        printf("VOCÊ JÁ LEU ESSE LIVRO? (INSIRA NO FORMATO: LIDO/LEITURA PENDENTE) ");
        scanf("%s", &lib[i].livro_lido);

        fprintf(pArq,"%d ",lib[i].num_livro);
        fprintf(pArq,"%s ",lib[i].nome_livro);
        fprintf(pArq,"%s ",lib[i].autor);
	    fprintf(pArq," %d ",lib[i].pags);
	    fprintf(pArq," %s \n",lib[i].livro_lido);
    }
	    
    fclose(pArq);
}

void visualizar()
{
    pArq = fopen("biblioteca.txt", "r");
    if(pArq == NULL){
    printf("Erro na abertura do arquivo!");
    return 1;  
    }

	int i = 0;
    for (i = 0; i < TAM; i++) {

            if (lib[i].num_livro != 0){

                printf("\t LIVRO NÚMERO = %d", lib[i].num_livro);
  
                printf("\t NOME DO LIVRO = %s", lib[i].nome_livro);
  
                printf("\t NOME DO AUTOR = %s", lib[i].autor);
  
                printf("\t  QUANTIDADE DE PAGINAS = %d", lib[i].pags);
  
                printf("\t  STATUS DE LEITURA = %s \n", lib[i].livro_lido);
                }
    }

	printf("\n");
	getchar();
	fflush(stdin);    
	system("pause");
	
}

 

  • Obrigado 1
Postado

@Amanda Umlauf

1 hora atrás, Amanda Umlauf disse:
scanf("%s", &lib[i].nome_livro);

Não precisa do & para ler strings com scanf(), e se quiser colocar, indique a posição da string na qual deve ser iniciada a gravação dos dados: &lib[i].nome_livro[0].

Se quer ler strings com espaços também, já que a maioria dos livros têm ao menos um espaço, pode usar como especificador %[^\n], isso faz com que a leitura só se encerre quando for encontrado um \n.

 

1 hora atrás, Amanda Umlauf disse:
scanf("%s", &lib[i].autor);

O mesmo vale pra isso.

 

1 hora atrás, Amanda Umlauf disse:
scanf("%s", &lib[i].livro_lido);

E isso.

 

1 hora atrás, Amanda Umlauf disse:
void abrir_arq(){
	pArq = fopen("biblioteca.txt", "a");
    if(pArq == NULL){
    printf("Erro na abertura do arquivo!");
    return 1;  
    }
return 0;
}

Declare a função como por exemplo int pra retornar um inteiro.

 

1 hora atrás, Amanda Umlauf disse:
void visualizar()

O mesmo vale pra isso.

 

1 hora atrás, Amanda Umlauf disse:
for(i=0;i<1;i++)

Pra que esse loop? Só vai rodar uma vez.

Aliás, você está cadastrando sempre na posição 0 de lib.

Você precisa de um contador que indique quantos livros já foram cadastrados, daí pode efetuar o cadastro usando ele de índice em lib.

 

1 hora atrás, Amanda Umlauf disse:

Ele mostra apenas o ultimo.

Acho que o problema é justamente a falta do contador :D

Aliás...

1 hora atrás, Amanda Umlauf disse:
for (i = 0; i < TAM; i++) {

Troque esse TAM pela variável responsável pela contagem, faça com que a função visualizar() receba esse valor, não trabalhe apenas com void funcao(void), isso só dificulta tudo.

  • Curtir 1
  • Amei 1
Postado
4 horas atrás, Amanda Umlauf disse:

Podem ter algumas coisas erradas no código em geral, eu meio que to fazendo e aprendendo ao mesmo tempo

 

O início de seu código

 

#define TAM 100


FILE *pArq; 

typedef struct biblioteca {
    char nome_livro[500], autor[500], livro_lido[500];
    int pags, num_livro;
}cad;
cad lib[TAM];


void cadastrar(); 
void visualizar(); 

 

Pois é: só isso já condena muito de seu programa e leva o tempo para desenvolver e testar para as alturas.

 

Recomendo MUITO reescrever. Leva pouco tempo se considerar o que vou te explicar e claro leva bem menos do que insistir nesse caminho.

 

Antes de tudo: escreva em torno dos dados. O que são os dados em seu programa? Um cadastro de livros.

 

De volta ao código original

 

FILE* pArq;

 

Está declarando um ponteiro GLOBAL. Por si só uma ideia ruim e condenada ou proibida em toda parte, escolas e empresas. E nunca declare um ponteiro e deixe sem inicializar. Nesse caso é óbvio que vai usar isso para abrir um arquivo então use o simples e seguro

 

    FILE*    pArq = fopen("biblioteca.txt", "a");

 

É muito mais seguro e legível.

 

typedef struct biblioteca
{
    char nome_livro[500], autor[500], livro_lido[500];
    int  pags, num_livro;
} cad;

 

Não escreva assim.

Escreva, como eu disse, em torno dos dados. Essa estrutura deveria ser um cadastro de livros.

  • Como pode não ter uma estrutura para livro?
  • Como pode a biblioteca ser um conjunto de 3 vetores de 500 campos que deveriam ser de cada livro?
  • porque só tem um pags se é supostamente o número de páginas de cada livro?
  • se cada livro tem um número porque não são 500 num_livro também?  Entendi errado?
void cadastrar();
void visualizar();

 

Não escreva isso. Uma função sem argumentos em geral é um erro. Uma função que retorna void pode ser no mínimo um desperdício.

 

O que é cadastrar? 

 

Você quer cadastrar um livro em uma biblioteca e parece que cabem 500 livros no acervo.

 

O esperado de cadastrar é cadastrar algo em algum lugar. No seu caso obviamente é cadastrar um Livro em uma Biblioteca. E pode não caber, porque parece que cabem 500 ou 100 livros no acervo...

 

Então porque não usar

 


int cadastrar( Livro* livro, Lib* bib );

 

para fazer o esperado e retornar zero se deu certo ou um código para um possível erro?

 

Os seus dados

 

typedef struct biblioteca
{
    char nome_livro[500], autor[500], livro_lido[500];
    int  pags, num_livro;
} cad;
cad lib[TAM];

 

notou que a struct tem 2 nomes? biblioteca e cad. Para que? E ela não é nem um cadastro nem uma biblioteca. É uma coleção de vetores de campos...

 

Compare

 

#define TAM_LIB 100

typedef struct
{
    unsigned id;
    char     nome[50];
    char     autor[50];
    char     lido;
    unsigned pags;
} Livro;

typedef struct
{
    unsigned id;
    unsigned N; // quantos livros
    unsigned limite; // capacidade
    Livro    obra[TAM_LIB]; // os livros

}   Acervo;

int cadastrar(Livro*, Acervo*); // o simples
int visualizar(Acervo*);

 

Escrevendo em torno dos dados, antes de escrever uma linha de programa, já se tem o item, o Livro, e o cadastro, Acervo.

 

E se pode declarar funções considerando essa realidade. E passando os argumentos, de modo que se pode ter várias bibliotecas por exemplo. 

 

É muito mais simples.

 

        printf(
            "\n\n--------------"
            " BEM-VINDO A SUA BIBLIOTECA "
            "----------------\n");
        printf(
            "\n\n *Utilize os números para navegar no "
            "menu* \n");
        printf("\n\n-------------------------\n");
        printf("1. ADICIONAR UM LIVRO NOVO\n ");
        printf("2. MOSTRAR LIVROS CADASTRADOS\n");
        printf("6. SAIR");

        printf("\n\nESCOLHA UMA DAS opções ACIMA: ");

 

Não escreva isso. Use um único printf(). É dezenas de vezes mais rápido para rodar e muito mais fácil de ler, de alinhar e de escrever.

 

Compare

 

        printf("\
\n\
\n\
--------------\n\
 BEM-VINDO A SUA BIBLIOTECA\n\
 ----------------\n\
\n\
\n\
 *Utilize os números para navegar no menu*\n\
\n\
\n\
-------------------------\n\
 1. ADICIONAR UM LIVRO NOVO\n\
 2. MOSTRAR LIVROS CADASTRADOS\n\
 6. SAIR\n\
\n\
\n\
    ESCOLHA UMA DAS opções ACIMA: ");

 

Mais simples de ler e de alinhar e roda muito mais rápido, já que chama uma única função...

 

        scanf("%d", &opcao);

 

TESTE sempre o retorno de scanf(). É ingênuo não testar. 

 

Se tem um menu use uma função que retorna a opção. É muito mais simples e fica muito mais fácil de ler o código....

 

    int menu();

 

    getchar();
    fflush(stdin);
    system("pause");

 

NÃO use system(). Não estará fazendo nada nem aprendendo nada.

 

fflush() só está definido para a saída e no modo normal de operação da console nunca vai ter o efeito que se imagina

 

Não pare o programa no final. Se seu IDE não consegue fazer isso MUDE de IDE. Não teste seus programas apenas no IDE. Vai precisar de duas versões se seu instrutor for corrigir o programa automaticamente?

 

Arquivos em C

 

Usar arquivos em C é trivial. E a razão é simples: essa linguagem foi criada para facilitar a missão de escrever um sistema operacional, o Unix, No Unix --- que virou Linux de onde vem o Android e o MacOS. E nesse sistema TUDO é arquivo. Memória, dispositivos e claro arquivos. Todo programa em C começa com 3 arquivos abertos, stdin, stdout e stderr, por exemplo.

 

Se tudo é um arquivo então o pessoal que criou isso não poderia atirar no próprio pé e fazer isso difícil certo?

 

O normal para o que está querendo fazer é manipular o Acervo na memória e gravar no disco no fim. E no disco gravar em blocos. De que tamanho? Do tamanho de um Livro. E ler um livro por vez. Não se usa texto. É muito mais difícil usar fprintf() e gravar um campinho por vez... Se usa fread() e fwrite() e trata tudo em termos de Livro.

 

E claro ler no início um eventual Acervo já existente, cujo nome seria passado no início do programa...

 

 

 

 

  • Curtir 1
  • Amei 1

Crie uma conta ou entre para comentar

Você precisa ser um usuário 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 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...