--- /dev/null
+#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);
+ }
+}