Home RecentChanges

Livros

Ficheiro livros.c:

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

#include <assert.h>

#define NUMEROLIVROS 100 
#define MAXTITULO 40 
#define MAXNOME 20 

typedef struct {
  int dia;
  int mes;
  int ano;
} Data;

typedef struct {
  char titulo[MAXTITULO];
  char autor[MAXNOME];
  long long int isbn;
  int anoPublicacao;
  int numeroDaCopia;
  Data dataEmprestimo;
  Data dataRetorno;
} Livro;

static Livro biblioteca[NUMEROLIVROS];
static size_t bibcount;

/*
 * ****BIBLIOTECA DO IST**** 
 * 1 - Inserir novo livro 
 * 2 - Listar livros 
 * 3 - Procurar livro por isbn 
 * 4 - Procurar livro por título 
 * 5 - Alterar título do livro 
 * 6 - Apagar livro pelo isbn 
 * 7 - Registar data de empréstimo de um livro pelo isbn 
 * 8 - Registar data de retorno de um livro pelo isbn 
 * 0 - Sair 
 * ************************* 
 */

void inserir_livro();
void listar_livros();
void apagar_livro();
void alterar_titulo();

void procurar_livro(int tipo);
int procurar_livro_por_isbn(long long int isbn);
int procurar_livro_por_nome(char nome[]);

void registar_emprestimo(int retorno);

int menu();
int le_linha(char buffer[], int max);
int le_opcao();
long long int le_isbn();
void le_titulo(char nome[]);

void mostra_livro(int i);

int
main()
{
  int opcao;

  while ((opcao = menu()) != 0) {
    switch (opcao) {
      case 1:
        inserir_livro();
        break;
      case 2:
        listar_livros();
        break;
      case 3:
        procurar_livro(0);
        break;
      case 4:
        procurar_livro(1);
        break;
      case 5:
        alterar_titulo();
        break;
      case 6:
        apagar_livro();
        break;
      case 7:
        registar_emprestimo(0);
        break;
      case 8:
        registar_emprestimo(1);
        break;
      default:
        assert(0);
    }
  }

  return EXIT_SUCCESS;
}

int
menu()
{
  int opcao;

  printf("****BIBLIOTECA DO IST****\n1 - Inserir novo livro\n2 - Listar livros\n3 - Procurar livro por isbn\n4 - Procurar livro por título\n5 - Alterar título do livro\n6 - Apagar livro pelo isbn\n7 - Registar data de empréstimo de um livro pelo isbn\n8 - Registar data de retorno de um livro pelo isbn\n0 - Sair\n*************************\n");

  opcao = le_opcao();
  while (opcao < 0 || opcao > 8) {
    printf("Opção inválida!\n");
    opcao = le_opcao();
  }

  return opcao;
}

/* Esta funcao le uma linha para buffer, ate' caber, e limpa os
 * restantes caracteres até encontrar um '\n' ou um EOF. */
/* Se buffer for NULL e max for 0, esta funcao permite limpar 
 * os caracteres ate ao final da linha ou EOF. */
int
le_linha(char buffer[], int max)
{
  int  i = 0, c;

  c = getchar();
  while (c != '\n' && c != EOF) {
    if (i < max - 1)
      buffer[i++] = c;
    c = getchar();
  }

  if (buffer)
    buffer[i] = '\0';

  return i;
}

int
le_opcao()
{
  int c, o = 0;

  while ((c = getchar()) != '\n' && c != EOF)
    o = o*10 + (c - '0');

  return o;
}

long long int
le_isbn()
{
  long long int isbn;

  printf("ISBN: ");
  scanf("%Ld", &isbn);
  le_linha(NULL, 0); /* Limpa o lixo. */

  return isbn;
}

void
le_titulo(char nome[])
{
  printf("Nome: ");
  le_linha(nome, MAXTITULO);
}

void
inserir_livro()
{
  if (bibcount < NUMEROLIVROS) {

    printf("Título: ");
    le_linha(biblioteca[bibcount].titulo, MAXTITULO);

    printf("Autor: ");
    le_linha(biblioteca[bibcount].autor, MAXNOME);

    printf("ISBN: ");
    scanf("%Ld", &biblioteca[bibcount].isbn);
    le_linha(NULL, 0); /* Limpa o lixo. */

    printf("Ano de publicação: ");
    scanf("%d", &biblioteca[bibcount].anoPublicacao);
    le_linha(NULL, 0); /* Limpa o lixo. */

    printf("Cópia: ");
    scanf("%d", &biblioteca[bibcount].numeroDaCopia);
    le_linha(NULL, 0); /* Limpa o lixo. */

    /* Inicializa datas de emprestimo e retorno */
    biblioteca[bibcount].dataEmprestimo.ano = 1970;
    biblioteca[bibcount].dataEmprestimo.mes = 1;
    biblioteca[bibcount].dataEmprestimo.dia = 1;
    biblioteca[bibcount].dataRetorno.ano = 1970;
    biblioteca[bibcount].dataRetorno.mes = 1;
    biblioteca[bibcount].dataRetorno.dia = 1;

    bibcount ++;
  }
}

void
mostra_livro(int i)
{
  if (i >= 0 && i < bibcount)
    printf("\"%s\", por %s, %d (isbn:%Ld) #%d: %d-%d-%d %d-%d-%d",
        biblioteca[i].titulo,
        biblioteca[i].autor,
        biblioteca[i].anoPublicacao,
        biblioteca[i].isbn,
        biblioteca[i].numeroDaCopia,
        biblioteca[i].dataEmprestimo.ano,
        biblioteca[i].dataEmprestimo.mes,
        biblioteca[i].dataEmprestimo.dia,
        biblioteca[i].dataRetorno.ano,
        biblioteca[i].dataRetorno.mes,
        biblioteca[i].dataRetorno.dia);
}

void
listar_livros()
{
  int i;

  printf("Inventário:\n");
  for (i = 0; i < bibcount; i++) {
    putchar('\t');
    mostra_livro(i);
    putchar('\n');
  }
  printf("\n");
}

/* Como o vector nao esta ordenado, temos de procurar de forma linear
 * percorrendo, eventualmente, todo o vector. */
void
procurar_livro(int tipo)
{
  long long int isbn;
  char titulo[MAXTITULO];

  /* Tipo 0 correponde a procura por ISBN */
  /* Tipo 1 correponde a procura por titulo */

  if (tipo == 0) {
    isbn = le_isbn();
    printf("Resultado:\n\t");
    mostra_livro(procurar_livro_por_isbn(isbn));
    printf("\n");
  } else if (tipo == 1) {
    le_titulo(titulo);
    printf("Resultado:\n\t");
    mostra_livro(procurar_livro_por_nome(titulo));
    printf("\n");
  }
}

/* Se o valor de retorno for maior ou igual a bibcount, entao nao
 * existem livros com o isbn indicado */
int
procurar_livro_por_isbn(long long int isbn)
{
  int i;
  for (i = 0; i < bibcount; i++)
    if (biblioteca[i].isbn == isbn)
      break;

  return i;
}

/* Se o valor de retorno for maior ou igual a bibcount, entao nao
 * existem livros com o titulo indicado */
int
procurar_livro_por_nome(char nome[])
{
  int i;
  for (i = 0; i < bibcount; i++)
    if (strcmp(biblioteca[i].titulo, nome) == 0)
      break;

  return i;
}

void
alterar_titulo()
{
  long long int isbn;
  int i;

  isbn = le_isbn();

  /* Comecar por procurar o livro em questao */
  i = procurar_livro_por_isbn(isbn);

  /* Se o livro existir... */
  if (i < bibcount) {
    printf("Título: ");
    le_linha(biblioteca[i].titulo, MAXTITULO);
    printf("Alteração:\n\t");
    mostra_livro(i);
    printf("\n");
  } else {
    printf("O livro com o ISBN %Ld não existe!\n", isbn);
  }
}

/* Por forma a manter as posicoes ocupadas de forma contigua, i.e.,
 * sem buracos, sempre que apagamos um livro, vamos copiar o elemento
 * na ultima posicao para a posicao que fica livre. Notar que a copia
 * ocorre campo a campo, em particular temos de utilizar o strcpy para
 * copiar o titulo e o autor. */
void
apagar_livro()
{
  long long int isbn;
  int i;

  isbn = le_isbn();

  /* Comecar por procurar o livro em questao */
  i = procurar_livro_por_isbn(isbn);

  /* Se o livro existir... */
  if (i < bibcount) {
    printf("Apagado:\n\t");
    mostra_livro(i);
    printf("\n");

    /* Copiar dados do livro na ultima posicao, caso i nao seja a
     * ultima posicao. */
    /* Comecamos por reduzir o numero de livros, i.e., descartar a
     * ultima posicao. */
    bibcount --;
    if (i != bibcount) {
      strcpy(biblioteca[i].titulo, biblioteca[bibcount].titulo);
      strcpy(biblioteca[i].autor, biblioteca[bibcount].autor);
      biblioteca[i].isbn = biblioteca[bibcount].isbn;
      biblioteca[i].anoPublicacao = biblioteca[bibcount].anoPublicacao;
      biblioteca[i].numeroDaCopia = biblioteca[bibcount].numeroDaCopia;
      biblioteca[i].dataEmprestimo = biblioteca[bibcount].dataEmprestimo;
      biblioteca[i].dataRetorno = biblioteca[bibcount].dataRetorno;
    }
  } else {
    printf("O livro com o ISBN %Ld não existe!\n", isbn);
  }
}

/* Esta funcao nao faz qualquer validacao, como por exemplo se o
 * livro ja esta emprestado, a nao foi devolvido, antes de fazer um
 * novo emprestimo. Fica para exercicio acrescentar as validacoes. */
void
registar_emprestimo(int retorno)
{
  long long int isbn;
  int i;

  isbn = le_isbn();

  /* Comecar por procurar o livro em questao */
  i = procurar_livro_por_isbn(isbn);

  /* Se o livro existir... */
  if (i < bibcount) {
    printf("Data (YYYY-MM-DD): ");
    if (retorno == 0)
      scanf("%d-%d-%d",
          &biblioteca[i].dataEmprestimo.ano,
          &biblioteca[i].dataEmprestimo.mes,
          &biblioteca[i].dataEmprestimo.dia);
    else
      scanf("%d-%d-%d",
          &biblioteca[i].dataRetorno.ano,
          &biblioteca[i].dataRetorno.mes,
          &biblioteca[i].dataRetorno.dia);

    le_linha(NULL, 0); /* Limpa o lixo. */
  } else {
    printf("O livro com o ISBN %Ld não existe!\n", isbn);
  }
}

Compilação e execução:

[aplf@darkstar iaed]$ gcc -Wall -ansi -o livros livros.c 
[aplf@darkstar iaed]$ ./livros 
****BIBLIOTECA DO IST****
1 - Inserir novo livro
2 - Listar livros
3 - Procurar livro por isbn
4 - Procurar livro por título
5 - Alterar título do livro
6 - Apagar livro pelo isbn
7 - Registar data de empréstimo de um livro pelo isbn
8 - Registar data de retorno de um livro pelo isbn
0 - Sair
*************************
1
Título: Programacao em C
Autor: Mr Random
ISBN: 123456789
Ano de publicação: 2008
Cópia: 1
****BIBLIOTECA DO IST****
1 - Inserir novo livro
2 - Listar livros
3 - Procurar livro por isbn
4 - Procurar livro por título
5 - Alterar título do livro
6 - Apagar livro pelo isbn
7 - Registar data de empréstimo de um livro pelo isbn
8 - Registar data de retorno de um livro pelo isbn
0 - Sair
*************************
1
Título: Programacao em Python
Autor: Mr Joe
ISBN: 2010
Ano de publicação: 2010
Cópia: 1
****BIBLIOTECA DO IST****
1 - Inserir novo livro
2 - Listar livros
3 - Procurar livro por isbn
4 - Procurar livro por título
5 - Alterar título do livro
6 - Apagar livro pelo isbn
7 - Registar data de empréstimo de um livro pelo isbn
8 - Registar data de retorno de um livro pelo isbn
0 - Sair
*************************
2
Inventário:
	"Programacao em C", por Mr Random, 2008 (isbn:123456789) #1: 1970-1-1 1970-1-1
	"Programacao em Python", por Mr Joe, 2010 (isbn:2010) #1: 1970-1-1 1970-1-1

****BIBLIOTECA DO IST****
1 - Inserir novo livro
2 - Listar livros
3 - Procurar livro por isbn
4 - Procurar livro por título
5 - Alterar título do livro
6 - Apagar livro pelo isbn
7 - Registar data de empréstimo de um livro pelo isbn
8 - Registar data de retorno de um livro pelo isbn
0 - Sair
*************************
0
[aplf@darkstar iaed]$