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]$