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