Estrutura de dados - cadeia
Publicado por Perfil removido 11/01/2005
[ Hits: 6.755 ]
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
[C] Manipulação de vetores/ponteiros
Fibonacci Recursivo e Não Recursivo
IA Turbina o Desktop Linux enquanto distros renovam forças
Como extrair chaves TOTP 2FA a partir de QRCODE (Google Authenticator)
Linux em 2025: Segurança prática para o usuário
Desktop Linux em alta: novos apps, distros e privacidade marcam o sábado
IA chega ao desktop e impulsiona produtividade no mundo Linux
Atualizando o Fedora 42 para 43
Como saber se o seu e-mail já teve a senha vazada?
Como descobrir se a sua senha já foi vazada na internet?
Programa fora de escala na tela do pc (33)
Eu queria adicionar a incon do wifi e deixa transparente no fluxbox no... (0)









