4646T-2 - Programação de Baixo Nível
Prof. Márcio Sarroglia Pinho


LEITOR DE PALAVRAS


DESCRIÇÃO GERAL

O objetivo deste trabalho é a implementação de um programa para gerenciar a coleta de palavras de um arquivo texto e a inserção destas em uma estrutura dinâmica que deverá separar as palavras de acordo com sua letra inicial. As palavras do texto deverão ter tamanho máximo de 15 caracteres.


A principal estrutura de dados deste programa deve ser um vetor de 26 ponteiros, destsa forma:

char *Palavras[TAM_ALFABETO
];

Cada entrada deste vetor deverá armazenar um ponteiro para uma sequência de null-terminated strings. A primeira entrada deve armazenar todas as palavras iniciadas pela letra  ‘A’, a segunda pela letra ‘B’, a terceira pela letra ‘C’ e assim sucessivamente, até a última entrada, que deverá armazenar as palavras iniciadas com a letra ‘Z’.


INICIALIZAÇÃO DO PROGRAMA

Ao iniciar o programa todos os ponteiros do vetor Palavras devem ser nulos:

void InicializaVetorPalavras(char* Palavras[])
{
    int i;
    for(i = 0; i < TAM_ALFABETO; i++)
        Palavras[i] = NULL;
}

Ao ler uma palavra do arquivo, o programa deverá descartar todos os símbolos de pontuação.

Palavras com mais de 15 caracteres devem ser descartadas.



ACESSO À ESTRUTURA DE DADOS

Para acessar a estrutura de dados deverão ser criadas as funções descritas a seguir.

•    void AdicionaPalavra(char* Palavras[], char* palavra)
Esta função deve adicionar uma palavra na estrutura Palavras. Ao inserir a primeira palavra de uma certa letra na estrutura, a entrada correspondente à palavra deve ter memória alocada para 20 caracteres. Na próximas inserções, o programa deve verificar se a memória disponível ainda é capaz de armazenar a nova palavra. Se não for, mais 20 caracteres devem ser alocados nesta lista.
Cada nova string inserida em uma das listas deve ser colocada logo após a última string inserida na lista. O separador entre estas strings deve ser o próprio terminador das strings de C. Para marcar o final de uma sequência de palavras, o programa deve colocar uma string nula (caracter ASCII == 0).

•    void ImprimePalavrasDeUmaLetra(char* Palavras[]), char letra);
Esta função deverá imprimir todas as palavras existentes na estrutura, que iniciam com uma determinada letra. As palavras devem ser impressas na ordem em que estas foram inseridas na estrutura. Esta ordem deve respeitar a ordem em que as palavras aparecem no texto.

•    void ImprimeTodasAsPalavras(char* Palavras[])
Esta função deverá imprimir todas as palavras existentes na estrutura. Incialmente devem ser impressas todas as palavras que iniciam com a letra A, depois B, e assim por diante. A função deve usar a função ImprimePalavrasDeUmaLetra para imprimir cada lista de palavras.

•    void ImprimeQuantidadeDeMemoriaGasta(char* Palavras[])
Esta função deve varrer as listas determinar quanto de memória, em bytes, foi alocado para cada uma delas. Esta quantidade deve ser impressa na tela, para cada uma das listas.
Note que este cálculo deve ser feito varrendo cada uma das listas, não sendo permitido armazenar uma informação extra sobre o tamanho das listas.


•    void CompactaListas(char* Palavras[])
Esta função deve ser capaz de compactar as listas de forma a remover destas o espaço não utilizado. Após a execução desta função todas as demais funções do programa devem continuar funcionando. Caso isto não ocorra, além do desconto neste item específico, será aplicado um desconto nos itens que passarem a não funcionar.

ORGANIZAÇÃO DO PROGRAMA
O programa deve, obrigatoriamente, usar como base o código fonte apresentado a seguir.
O programa deve seguir rodando até que seja selecionada a opção de encerramento.


  1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// ***************************************************************
// Programação de Baixo Nível
// Trabalho II - 2016-1
// Dúvidas: [email protected]
// ***************************************************************

#include <stdio.h>
#define TAM_ALFABETO 26
#define NOME_ARQ "Texto1.txt"

// ***************************************************************
// Esta função é capaz de imprimir uma lista de string armazenadas
// uma após a outra e separadas apenas pelo NULL que marca do fim de
// uma string em C. Para marcar o final da lista um NULL de ser
// colocado após o NULL da última string.
// ***************************************************************
void ImprimeStrings(char* s)
{
char* ptr = s;
while(1) {
if(*ptr == 0)
break;
while(*ptr)
printf("%c", *ptr++);
printf("\n");
ptr++;
}
}

// ***************************************************************
//
// ***************************************************************
void ImprimeTodasAsPalavras(char* Palavras[])
{
}

// ***************************************************************
//
// ***************************************************************
void ImprimePalavrasDeUmaLetra(char* Palavras[], char letra)
{
}

// ***************************************************************
//
// ***************************************************************
void ImprimeMenu()
{
printf("\n\n\n1 - Imprime Todas as Palavras.\n");
printf("2 - Imprime as Palavras de uma Letra.\n");
printf("3 - Imprime Quantidade de Memoria Gasta.\n");
printf("4 - Compacta Listas.\n");
printf("0 - Sai.\n");
}

// ***************************************************************
//
// ***************************************************************
void LeOpcao(int* opcao)
{
scanf("%d", opcao);
printf("Opcao Lida: %d\n", *opcao);
}

// ***************************************************************
//
// ***************************************************************
void TrataOpcao(int opcao, char* Palavras[])
{
char letra;
switch(opcao) {
case 1: // Imprime Todas as palavras
ImprimeTodasAsPalavras(Palavras);
break;
case 2: // Imprime as palavras de uma letra
printf("Digite uma letra: ");
scanf(" %c", &letra); // Este SCANF está sendo ignorado
printf("Letra escolhida: %c\n", letra);
ImprimePalavrasDeUmaLetra(Palavras, letra);
break;
// ... Adicione aqui o tratamento das demais opções
}
}

// ***************************************************************
//
// ***************************************************************
void AdicionaPalavra(char* Palavras[], char* palavra)
{
printf("Palavra Adicionada: %s\n", palavra);
// Esta função de remover todos os simbolos de pontuacao que existirem na
// palavra informada como parâmetro
}
// ***************************************************************
// Faz a inicialização dos ponteiros do vetor de pointeiros
// que guarda as palavras
// ***************************************************************
void InicializaVetorPalavras(char* Palavras[])
{
int i;
for(i = 0; i < TAM_ALFABETO; i++)
Palavras[i] = NULL;
}
// ***************************************************************
//
// ***************************************************************
int LeArquivo(char* Palavras[])
{
FILE* arquivo;
int retorno;
char palavra[100];

arquivo = fopen(NOME_ARQ, "rt");
if(arquivo == NULL) {
printf("Problemas na abertura do arquivo de entrada!\n");
return -1;
} else
printf("Abertura OK !\n");
do {
retorno = fscanf(arquivo, "%s", palavra); // lê a proxima string o arquivo
if(retorno == EOF)
break;
AdicionaPalavra(Palavras, palavra);
} while(1);
fclose(arquivo);
printf("Leitura concluida !\n");
return 0;
}
// ***************************************************************
//
// ***************************************************************
int main()
{
// char lista[] = { 'a', 'b', 'c', 'd', 0, 'a', 'a', 'a', 0, 'a', 'b', 'c', 'd', 0, 0 };
// ImprimeStrings(lista);
char* Palavras[TAM_ALFABETO];
int retorno, opcao;

InicializaVetorPalavras(Palavras);
retorno = LeArquivo(Palavras);
if(retorno == -1)
return 0; // termina o programa pois houve erro na leitura do arquivo
do {
ImprimeMenu();
LeOpcao(&opcao);
if(opcao == 0)
break;
TrataOpcao(opcao, Palavras);
} while(1);

return 0;
}



OBSERVAÇÕES

As funções deste programa não poderão ter mais do que 20 linhas
(-2.0 pontos).

Os vetores do programa devem ser manipulados com ponteiros e não com índices(-2.0 pontos).



FIM.