12.1
12
EXERCÍCIOS PROPOSTOS – SOLUÇÃO
1: #include <stdio.h>
2: #include <string.h>
3: #include <stdlib.h>
4: 5: char *repete(char *string, int n)
6: {
7: char *aux; 8:
9: if (n==0)
10: return strdup(""); 11:
12: if ((aux=(char *) calloc(n, strlen(string)+1))==NULL)
13: return aux; /* NULL */ 14:
15: for (int i=1; i<=n; i++)
16: { 17: strcat(aux, string);
18: if (i!=n)
19: strcat(aux, " ");
20: }
21:
22: return aux; 23: }
24:
25: int main(void)
26: {
27: char * ptr;
28: for (int i=4; i>=0; i--)
29: { 30: ptr = repete("Ola", i); 31: printf("|%s|\n", ptr);
32: free(ptr); 33: }
34: return 0; 35: }
12.2
1: #include <stdio.h>
2: #include <string.h>
3: #include <stdlib.h>
4:
5: char *metade(char *s)
6: {
7: char * tmp = (char*) malloc(strlen(s)/2+1);
8: if (tmp==NULL)
9: return tmp; 10:
11: strncpy(tmp, s, strlen(s)/2); 12: tmp[strlen(s)/2]='\0';
13: return tmp; 14: }
15:
16: int main(void)
17: { 18: char * ptr; 19:
20: ptr = metade("alvoco"); 21: printf("|%s|\n", ptr); 22: free(ptr); 23:
24: ptr = metade("grave"); 25: printf("|%s|\n", ptr); 26: free(ptr); 27:
28: ptr = metade(""); 29: printf("|%s|\n", ptr); 30: free(ptr); 31:
32: return 0; 33: }
1: #include <stdio.h>
2: #include <string.h>
3: #include <stdlib.h>
4:
5: void troca(char *s1, char *s2)
6: { 7: char aux = *s1; 8: *s1 = *s2; 9: *s2 = aux; 10: }
11:
12: char *strrev(char *s)
13: { 14: int i, len; 15:
16: for (i=0, len=strlen(s)-1 ; i < len ; i++, len--)
17: troca(s+i, s+len); 18: return s; 19: }
20:
21: char *inverte(char *s)
22: { char *tmp = (char*) malloc(strlen(s)+1); 23: if (tmp==NULL) 24: return tmp; 25: 26: strcpy(tmp, s); 27: return strrev(tmp); 28: }
29:
30: int main(void)
31: { 32: char * ptr; 33:
34: ptr = inverte("roma"); 35: printf("|%s|\n", ptr);
36: free(ptr);
37:
38: ptr = inverte("Omississimo");
39: printf("|%s|\n", ptr); 40: free(ptr); 41: 42: ptr = inverte("");
43: printf("|%s|\n", ptr); 44: free(ptr); 45:
46: return 0; 47: }
12.4
1: typedef struct Item
2: { 3: unsigned int num; // nº positivo (ou zero)
4: struct Item *next; 5: } ITEM; 6:
7: ITEM *create_item(unsigned int id);
8: void print_item(ITEM *ptr); 9: void destroy_item(ITEM *ptr); }
1: #include <stdio.h>
2: #include <stdlib.h>
3: #include <string.h>
4: #include "item.h"
5:
6: // Create a new Item
7: ITEM *create_item(unsigned int num)
8: { 9: ITEM *ptr = malloc(sizeof(ITEM)); 10: if (ptr != NULL)
11: { 12: ptr->num = num; 13: ptr->next = NULL; 14: } 15: return ptr; 16: } 17:
18: void print_item(ITEM *ptr) 19: { 20: printf("[%d]\n", ptr->num); 21: } 22:
23: // Liberta a memória que pode ser sido criada 24: // dinamicamente no nó.
25: void destroy_item(ITEM *ptr)
26: { 27: // nada a fazer 28: }
ITEM.C
1: #include "item.h" 2:
3: typedef ITEM* LIST; 4:
5: // primitive functions
6: int size(LIST list);
7: int is_empty(LIST list); 8: int is_full(LIST list);
9:
10: unsigned int add_item(LIST *list, unsigned int num); 11: unsigned int remove_item(LIST *list, unsigned int num); 12:
13: // outras funções
14: void inic_list(LIST *list); 15: void print_list(LIST list, char *title); LIST.H
1: #include <stdio.h>
2: #include <string.h>
3: #include <stdlib.h>
4: #include "list.h"
5:
6: void inic_list(LIST *list)
7: {
8: *list = NULL;
9: }
10:
11: int size(LIST list)
12: {
13: if (list==NULL)
14: return 0;
15: return 1+size(list->next);
16: }
17:
18: int is_empty(LIST list)
19: {
20: return (list==NULL);
21: }
22:
23: int is_full(LIST list)
24: {
25: return 0; // always false
26: }
27:
28: // Adicionar um novo nº à lista
29: unsigned int add_item(LIST *list, unsigned int num)
30: {
31: if (num%2==1 || *list==NULL) // Ímpar ou lista vazia
32: {
33: ITEM *ptr = create_item(num);
34: if (ptr==NULL)
35: return 0; // problemas com alloc
36: ptr->next = *list;
37: *list = ptr;
38: return num;
39: }
40: else
41: return add_item(&(*list)->next, num);
42: }
43:
44: // Remover uma occ de num e devolve-o ou zero
45: unsigned int remove_item(LIST *list, unsigned int num)
46: {
47: if (is_empty(*list)) // Se lista vazia
48: return 0;
49:
50: if ((*list)->num != num) // Não é o valor a remover
51: return remove_item(&(*list)->next, num);
52:
53: // Encontrado o valor a remover
54: ITEM* aux = *list;
55: *list = (*list)->next;
56: aux->next = NULL; // Just in case...
57: free(aux);
58: return num;
59: }
60:
61: void print_list(LIST list, char *title)
62: {
63: printf("%s\t", title); 64: // Cabeçalho da lista
65: printf("list: {count: %d | isEmpty: %s}\n", 66: size(list), is_empty(list)? "Yes" : "No");
67:
68: while (!is_empty(list))
69: { 70: print_item(list);
71: list = list->next; 72: }
73: printf("\n"); 74: }
1: #include <stdio.h>
2: #include "list.h"
3:
4: int main(void)
5: {
6: LIST list; // Create a new list
7: inic_list(&list); // Inic the list
8:
9: print_list(list, "Print empty list"); 10:
11: for (int i=15; i>=10; i--)
12: if (add_item(&list, i))
13: printf("Added %d\n", i); 14:
15: print_list(list, "");
16:
17: add_item(&list, 17);
18: print_list(list, "Adding 17");
19:
20: add_item(&list, 13); 21: print_list(list, "Adding 13"); 22:
23: add_item(&list, 999);
24: print_list(list, "Adding 999");
25:
26: if (remove_item(&list, 13))
27: print_list(list, "Removing 13");
28: else
29: puts("Item 13 does not exist\n");
30:
31: if (remove_item(&list, 13))
32: print_list(list, "Removing 13 again");
33: else
34: puts("Item 13 does not exist\n"); 35:
36: if (remove_item(&list, 13))
37: print_list(list, "Removing 13 again");
38: else
39: puts("Item 13 does not exist\n");
40:
41: // remove all items
42: int value;
43: while (!is_empty(list))
44: if ((value=remove_item(&list, list->num)))
45: printf("Removed %d\n", value);
46:
47: print_list(list, "\nEmpty list\n");
48:
49: return 0;
50: }
a)
O código encontra-se na pasta demo-reg
1: typedef struct 2: { 3: char nome[30+1]; 4: float altura; 5: int idade; 6: } REG;
b)
c)
d)
8: REG arr[] = {{"Carlos", 1.85, 67}, 9: {"Beatriz", 1.62, 27}, 10: {"Sofia", 1.49, 50}, 11: {"Raquel", 1.72, 18} 12: };
13: REG extra = {"Bigfoot", 2.35, 25};
15: FILE * inic()
16: { 17: FILE *fp;
18: if ((fp=fopen(FILE_DATA, "wb+"))==NULL)
19: { 20: fprintf(stderr, "Impossível criar o ficheiro %s\n", FILE_DATA); 21: exit(1); 22: } 23:
24: long n_regs = sizeof(arr)/sizeof(REG); 25: if (fwrite(arr, sizeof(REG), n_regs, fp)!=n_regs)
26: { 27: fprintf(stderr, "Problemas na escrita dos registos\n"); 28: exit(2); 29: };
30:
31: return fp; 32: }
e)
f)
34: void print_record(REG rec)
35: { 36: printf("%-30s\t%.2fm\t%i anos\n", rec.nome, rec.altura, rec.idade); 37: }
39: void list_all(FILE *fp)
40: { 41: REG reg; 42:
43: // Ir para o início do ficheiro 44: rewind(fp); // fseek(fp, 0L, SEEK_CUR); 45: puts("--- List All ---");
g)
46: while (fread(®, sizeof(reg), 1, fp)==1)
47: {
48: printf("%lu: ", ftell(fp)/sizeof(reg));
49: print_record(reg);
50: }
51: puts("--- (end) ------\n");
52: }
54: void list_all_reverse(FILE *fp)
55: {
56: REG reg;
57: // Ir para o início do último registo
58: if (fseek(fp, -sizeof(reg), SEEK_END)!=0)
59: return; // problemas com o posicionamento
60:
61: puts("--- List All Reverse ---");
62: do
63: { 64: if (fread(®, sizeof(reg), 1, fp)!=1)
65: return; // não conseguiu ler
66: printf("%lu: ", ftell(fp)/sizeof(reg));
67: print_record(reg);
68: } // Andar 2 registos para trás
69: while (fseek(fp, -2*sizeof(reg), SEEK_CUR)==0);
70: puts("--- (end) ------\n");
71: }
h)
73: unsigned long count_records(FILE* fp)
74: {
75: // Posicionar no final do ficheiro
76: fseek(fp, 0L, SEEK_END);
77: return ftell(fp)/sizeof(REG);
78: }
i)
j)
80: void append_record(FILE* fp, REG reg)
81: { 82: fseek(fp, 0L, SEEK_END);
83: fwrite(®, sizeof(reg), 1L, fp); 84: } ... // Na função main()
157: append_record(fp, extra);
158: list_all(fp);
159: printf("Nº de registos: %lu\n\n", count_records(fp));
86: REG* read_record(FILE *fp, int pos)
87: { 88: REG *ptr = malloc(sizeof(REG));
89: if (ptr==NULL)
90: { 91: fprintf(stderr, "Não há memória suficiente.");
92: return NULL;
93: }
94:
95: // Posicionar-se antes do registo índice=(pos-1)
96: if (fseek(fp, (pos-1)*sizeof(REG), SEEK_SET)!=0)
97: { 98: fprintf(stderr, "Não existe um registo na posição %d\n", pos);
k)
99: free(ptr); 100: return NULL; 101: }
102:
103: // Ler o registo na posição onde estamos 104: if (fread(ptr, sizeof(REG), 1L, fp)!=1)
105: { 106: fprintf(stderr, "Não foi possível ler o registo na posição %d\n", pos); 107: free(ptr); 108: return NULL; 109: }
110:
111: return ptr; 112: }
113: void swap_records(FILE*fp, int pos1, int pos2) 114: { 115: REG *r1, *r2; 116:
117: if ((r1=read_record(fp, pos1))==NULL) 118: return;
119: if ((r2=read_record(fp, pos2))==NULL)
120: return;
121:
122: // Escrever r2 em pos1
123: fseek(fp, (pos1-1)*sizeof(REG), SEEK_SET); 124: fwrite(r2, sizeof(*r2), 1L, fp);
125:
126: // Escrever r1 em pos2
127: fseek(fp, (pos2-1)*sizeof(REG), SEEK_SET); 128: fwrite(r1, sizeof(*r1), 1L, fp);
129:
130: // Libertar a memória 131: free(r1); free(r2); 132: }
l)
m)
134: // Cria uma estrutura dinamicamente para 135: // conter todos os registos do ficheiro 136: REG* load_all(FILE*fp) 137: {
138: long count = count_records(fp); 139: REG *arr = malloc(count*sizeof(REG)); 140: 141: if (arr==NULL)
142: return NULL; 143:
144: fseek(fp, 0L, SEEK_SET); 145: fread(arr, sizeof(REG), count, fp); 146: return arr; 147: }
149: int main(void) 150: { 151: FILE *fp = inic(); 152:
153: list_all(fp); 154: list_all_reverse(fp); 155: printf("Nº de registos: %lu\n\n", count_records(fp)); 156: 157: append_record(fp, extra);
158: list_all(fp);
159: printf("Nº de registos: %lu\n\n", count_records(fp));
160: 161: swap_records(fp, 1, 5);
162: list_all(fp);
163: printf("Nº de registos: %lu\n\n", count_records(fp));
164:
165: REG *regs = load_all(fp); 166: puts("--- Registos em memória ---"); 167: for (int i=0; i<count_records(fp); i++)
168: {
169: printf("regs[%d] : ", i); 170: print_record(regs[i]);
171: }
172: puts("---------------------------");
173:
174: free(regs); 175: fclose(fp); 176: return 0; 177: }