Estrutura de dados - cadeia

Publicado por Perfil removido 11/01/2005

[ Hits: 6.604 ]

Download cadeias.c




Permite algumas flexibilidades no trabalho de strings, mas está aí mais como um exmplo de estrutura de dados do que qualquer outra coisa...
É uma estrutura simples, tem um ponteiro pro conteúdo e um inteiro com o tamanho...
Criei para exemplificar a criação de abstrações.
Como nao eh possivel fazer upload de mais de um arquivo, colocquei
os arquivos cadeia.c e cadeia.h num arquivo cadeias.c.
Nao esqueçam de colocar os conteúdos nos lugares certos...

  



Esconder código-fonte

//Aqui comeca o arquivo cadeia.h



#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#ifndef _CADEIA_
#define _CADEIA_

typedef struct {
    char *conteudo;
    int tamanho;
    int capacidade;
} cadeia_t;

/* inicializa a cadeia apontada por cad com o valor da string C s.
   cad é considerada não inicializada na entrada da função.
   Se s não for NULL e apontar para uma string com tamanho maior
   que 0, deve ser alocada memória para conteudo e o valor apontado
   por s deve ser copiado para essa região. */
void cad_inicializa(cadeia_t * cad, char *s);

/* substitui o conteúdo da cadeia cad pelo conteúdo do arquivo de nome
   'nome'. Imprime erro e aborta se o arquivo não puder ser lido. */
void cad_le_arquivo(cadeia_t * cad, char *nome);

/* escreve a cadeia cad no arquivo de nome 'nome' */
void cad_escreve_arquivo(cadeia_t * cad, char *nome);

/* Libera a memória ocupada pela cadeia cad. Após a execução da função,
   cad deve conter tamanho 0 e conteúdo igual a NULL. */
void cad_destroi(cadeia_t * cad);

/* copia a cadeia cad para a região apontada por s. Complementar por um 
   caractere '{FONTE}'. É responsabilidade de quem chama garantir que s
   aponta para uma regiao suficientemente grande. */
void cad_string(cadeia_t * cad, char *s);

/* retorna o número de caracteres na cadeia cad. */
int cad_tamanho(cadeia_t * cad);

/* sub passa a ter "t" caracteres de cad, a partir do caractere no índice
   "p" (o primeiro de uma cadeia está no índice 0).
   Se p e t não representarem uma subcadeia válida de cad, a função deve
   imprimir uma mensagem dizendo isso e abortar a execução do programa.
   Se necessário, o conteúdo de sub deve ser realocado. */
void cad_subcadeia(cadeia_t * sub, cadeia_t * cad, int p, int t);

/* Substituir, em cad, a subcadeia delimitada por p e t (considerados
   como na função cad_subcadeia) pela cadeia sub. Se necessário, o conteúdo
   de cad deve ser realocado. */
void cad_substitui(cadeia_t * cad, int p, int t, cadeia_t * sub);

/* Imprime a string com uma quebra de linha no final */
void cad_imprime(cadeia_t * cad);

/* Compara duas cadeias e retorna menor que, igual a,
   ou maior que zero,se cad1 eh, respectivamente,
   menor que, igual ou maior que cad2. */
int cad_compara(cadeia_t * cad1, cadeia_t * cad2);

#endif


// Aqui termina o arquivo cadeia.h



//Aqui comeca o arquivo cadeia.c





#ifndef DEBUG

#include "cadeia.h"

#endif            /* 
 */

 void cad_inicializa(cadeia_t * cad, char *s) 

{
    
int i;
    
if (s == NULL) {
   
cad->tamanho = cad->capacidade = 0;
   
cad->conteudo = NULL;
   
return;
    
}
    
cad->capacidade = cad->tamanho = strlen(s);
    
if (cad->capacidade == 0) {
   
cad->conteudo = NULL;
   
return;
    
}
    
cad->conteudo = (char *) calloc(cad->capacidade, sizeof(char));
    
for (i = 0; i < cad->tamanho; i++) {
   
cad->conteudo[i] = s[i];
    
}

}


void cad_destroi(cadeia_t * cad) 

{
    
free(cad->conteudo);
    
cad->conteudo = NULL;
    
cad->capacidade = cad->tamanho = 0;

} 

void cad_le_arquivo(cadeia_t * cad, char *nome) 

{
    
FILE * arq;
    
int i;
    
if (nome == NULL) {
   
fprintf(stderr, "Erro! Nome de arquivo invalido\n");
   
abort();
    
}
    
if ((arq = fopen(nome, "r")) == (FILE *) NULL) {
   
fprintf(stderr, "Erro ao abrir arquivo %s\n", nome);
   
abort();
    
}
    
fseek(arq, 0, SEEK_END);
    
cad->capacidade = ftell(arq);   //Variavel capacidade obtem tam do arquivo

    rewind(arq);
    
if (cad->conteudo != NULL) {
   
cad->conteudo = (char *) realloc(cad->conteudo, cad->capacidade);
    
} else {
   
cad->conteudo = (char *) malloc(cad->capacidade);
    
} 
cad->tamanho = cad->capacidade;
    
i = 0;
    
while (i < cad->tamanho) {
   
cad->conteudo[i] = fgetc(arq);
   
i++;
    
}
    
fclose(arq);

}


int cad_tamanho(cadeia_t * cad) 

{
    
return cad->tamanho;

}


void cad_escreve_arquivo(cadeia_t * cad, char *nome) 

{
    
FILE * arq;
    
if ((arq = fopen(nome, "w")) == (FILE *) NULL) {
   
fprintf(stderr, "Erro ao criar arquivo %s\n", nome);
   
abort();
    
}
    
int i = 0;
    
while (i < cad->tamanho) {
   
putc(cad->conteudo[i], arq);
   
i++;
    
}
    
fclose(arq);

}


void cad_imprime(cadeia_t * cad) 

{
    
int i;
    
printf("[ ");
    
for (i = 0; i < cad->tamanho; i++)
   
putchar(cad->conteudo[i]);
    
printf(" ]\n");

}


void cad_string(cadeia_t * cad, char *s)
{
    
int i = 0;
    
while (i < cad->tamanho) {
   
s[i] = cad->conteudo[i];
   
i++;
    
}
    
s[i] = '{FONTE}';

}


void cad_subcadeia(cadeia_t * sub, cadeia_t * cad, int p, int t) 

{
    
int i = 0;
    
if (p < 0 || t < 0) {
   
fprintf(stderr, "Erro! Uso de indices invalidos\n");
   
abort();
    
}
    
if (p + t > cad->tamanho || cad->conteudo == NULL) {
   
fprintf(stderr, "Erro! Uso de subcadeia invalida!\n");
   
abort();
    
}
    
if (p + t > sub->capacidade && sub->conteudo != NULL) {
   
sub->conteudo =
       (char *) realloc(sub->conteudo, (sub->capacidade + t));
   
sub->capacidade += t;
    
}
    
if (sub->conteudo == NULL) {
   
sub->conteudo = (char *) malloc(t * sizeof(char));
   
sub->capacidade = t;
    
}
    
while (i <= t) {
   
sub->conteudo[i] = cad->conteudo[p];
   
i++;
   
p++;
    
}
    
sub->tamanho = t;

}


void cad_substitui(cadeia_t * cad, int p, int t, cadeia_t * sub) 

{
    
if (sub->conteudo == NULL) {
   
fprintf(stderr, "Erro! Uso de cadeia vazia!\n");
   
abort();
    
}
    

   //     void *memmove(void *dest, const void *src, size_t n);

   if (p < 0 || t < 0 || p + t > cad->tamanho) {
   
fprintf(stderr, "Erro! Uso de indices invalidos!\n");
   
abort();
    
}
    
if (cad->conteudo == NULL) {
   
cad_inicializa(cad, " ");
   
printf("%d", cad->tamanho);
    
}
    
if (sub->tamanho == t) {
   
memmove(&cad->conteudo[p], sub->conteudo, t);
    
} else {
   
int i, j, k;
   
i = p + sub->tamanho;
   
j = p + t;
   
k = cad->tamanho - p - t;
   
if (sub->tamanho < t) {
       
memmove(&cad->conteudo[p], sub->conteudo, t);
       
memmove(&cad->conteudo[i], &cad->conteudo[j], k);
       
cad->tamanho = cad->tamanho + sub->tamanho - t;
   
} else {
       
int tam = cad->tamanho + sub->tamanho - t;
       
if (tam > sub->capacidade) {
      
cad->conteudo = realloc(cad->conteudo, tam);
      
cad->capacidade = tam;
       
}
       
cad->tamanho = tam;
       
memmove(&cad->conteudo[i], &cad->conteudo[j], k);
       
memmove(&cad->conteudo[p], sub->conteudo, sub->tamanho);
   
}
    
}

}


int cad_compara(cadeia_t * cad1, cadeia_t * cad2) 

{
    
if (cad1 == NULL || cad2 == NULL) {
   
fprintf(stderr, "Cadeia nula!");
   
abort();
    
}
    
char str_aux1[cad1->tamanho + 1], str_aux2[cad2->tamanho + 1];
    
cad_string(cad1, str_aux1);
    
cad_string(cad2, str_aux2);
    
return strcmp(str_aux1, str_aux2);

}





// Fim do arquivo cadeia.c

Scripts recomendados

Resolução de uma fórmula de mátemática

Conversão do número de dias em anos (meu segundo programa em C)

Raiz quadrada aproximada

Constantes de barra invertida

Troco em cédulas


  

Comentários
[1] Comentário enviado por diego.ribas em 28/04/2005 - 03:05h

Dae guri!
publicando trabalhos? hehehe massa...
tive q fazer esse trabalho na cadeira tb.
é uma blibliotecazinha bem útil até!
feito!


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts