Estrutura de dados - cadeia
Publicado por Perfil removido 11/01/2005
[ Hits: 6.796 ]
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...
//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
Escolha o algoritmo de ordenação
Cirurgia para acelerar o openSUSE em HD externo via USB
Void Server como Domain Control
Modo Simples de Baixar e Usar o bash-completion
Monitorando o Preço do Bitcoin ou sua Cripto Favorita em Tempo Real com um Widget Flutuante
Como verificar a saúde dos discos no Linux
Como instalar , particionar, formatar e montar um HD adicional no Linux?
Como automatizar sua instalação do Ubuntu para desenvolvimento de software.
Servidor Ubuntu 24.04 HD 500 não tenho espaço na \home\adminis... (6)
Dá para criar um bom jogo usando a linguagem de programação C? (2)
Fiz uma pergunta no fórum mas não consigo localizar (8)
E como programar um sistema operacional inspirado no próprio linux usa... (3)









