Além das rotinas da biblioteca padrão e de suporte, há diversos aplicativos
que são diretamente suportados pela linguagem C. Estes aplicativos são
suportados em geral através de bibliotecas que podem ser ligadas ao código
da aplicação, como ocorre com rotinas da biblioteca padrão -- a diferença
é que neste caso estas bibliotecas de aplicativos devem ser explicitamente
indicadas para o compilador (por exemplo, através da chave -l<lib>
para o comando cc, onde <lib>
é uma indicação para a
biblioteca do aplicativo.
Em Unix, por exemplo, há uma biblioteca de rotinas que suporta a funcionalidade básica de um gerenciador de base de dados. Esta biblioteca, dbm, inclui rotinas que permitem:
Como pode se observar, dbm é uma biblioteca de funções de base de dados. Estas funções são disponíveis para o programador que necessita criar e manipular uma base de dados organizada através de uma função hash.
O uso convencional do dbm é através do armazenamento de pares chave/dado em um arquivo de dados. Cada chave deve ser única e associada a somente um item de dado.
Definições necessárias ao gerenciador estão incorporadas no arquivo de cabeçalho dbm.h. O tipo de dado datum define o componente básico de um registro, sendo este componente uma estrutura C na forma
typedef struct { char *dptr; int dsize; } datum;
Esta estrutura permite chaves e itens de dado de tamanhos arbitrários. Um registro da base de dados é composto por dois elementos do tipo datum [chave, dados].
As rotinas incorporadas à biblioteca do gerenciador são as seguintes:
Rotinas que retornam um inteiro indicam erro através de valores negativos; sucesso é indicado por um valor de retorno 0. Por outro lado, rotinas que retornam um datum indicam erro setando o valor de dptr igual a 0 na estrutura retornada.
Para ligar programas C com a biblioteca dbm, a chave de compilação
-ldbm deve ser incluída. Para executar os programas, dbm
requer que os arquivos correspondente à base de dados já existam. Para
criar os arquivos para uma base de dados de nome xxx, pode-se
utilizar o seguinte comando Unix:
touch xxx.dir xxx.pag.
O seguinte exemplo ilustra o uso desta biblioteca para armazenar dados em um arquivo com nomes e telefones:
/* * Armazena nome e telefone em um arquivo dbm "agenda" */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <dbm.h> /* define datum (typedef) */ #define ARQDBM "agenda" /* nome da base de dados */ int main(int argc, char *argv[]) { int erro; datum dbnome, dbfone; /* estruturas para dbm */ char nome[60], fone[20]; /* buffers para dados */ char comando[60]; /* buffer para comando */ /* ENTRADA DE DADOS */ if (argc > 3) { /* numero invalido de argumentos */ printf("Uso: %s [nome] [fone]\n",argv[0]); return(1); } else { if (argc == 1) { /* nenhum argumento fornecido */ printf("\tNome: "); gets(nome); printf("\tFone: "); gets(fone); } else if (argc == 2) { /* nome foi fornecido em argv[1] */ strcpy(nome,argv[1]); printf("\tFone: "); gets(fone); } else { /* nome e fone fornecidos */ strcpy(nome,argv[1]); strcpy(fone,argv[2]); } } /* CONVERSAO DOS DADOS PARA ESTRUTURA DATUM */ /* incluindo o ultimo '\0' nos strings */ dbnome.dptr = nome; dbnome.dsize = strlen(nome)+1; dbfone.dptr = fone; dbfone.dsize = strlen(fone)+1; /* ARMAZENA NA BASE DE DADOS */ /* -- prepara arquivos internos de dbm */ sprintf(comando,"touch %s.pag %s.dir", ARQDBM, ARQDBM); system(comando); /* -- abre base de dados */ erro = dbminit(ARQDBM); if (erro != 0) { /* imprime mensagem de erro */ perror("Abre agenda"); return(1); } /* -- armazena dados na agenda */ erro = store(dbnome,dbfone); if (erro != 0) { /* imprime mensagem de erro */ perror("Armazena em agenda"); return(1); } /* -- fecha base de dados */ erro = dbmclose(); if (erro != 0) { /* imprime mensagem de erro */ perror("Fecha agenda"); return(1); } /* -- tudo certo, saida sem erro */ return(0); }