#include <stdio.h> #include <stdlib.h> /* Macros relacionadas com o numero maximo de caracteres num nome e com o tamanho das matrizes de char necessarias para os guardar: */ #define NOME_MAX 40 #define NOMEMAT_MAX (NOME_MAX + 1) /* Macro que define o numero maximo de utentes: */ #define UTENTES_MAX 50 /* Definicao da estrutura que guarda informacao acerca de um utente: */ typedef struct Utente { char nome[NOMEMAT_MAX]; int categoria; int codigo; } Utente; /* Le utentes dum ficheiro. Devolve o numero de utentes lidos: */ int leUtentes(Utente utentes[], FILE *entrada) { int i; for(i = 0; i < UTENTES_MAX; i++) { if(fgets(utentes[i].nome, NOMEMAT_MAX, entrada) == NULL || fscanf(entrada, "%d%d ", &utentes[i].categoria, &utentes[i].codigo) != 2) break; if(utentes[i].nome[strlen(utentes[i].nome)-1] == '\n') utentes[i].nome[strlen(utentes[i].nome)-1] = '\0'; } return i; } /* Guarda lista de utentes num ficheiro (a informacao que existia no ficheiro e' descartada): */ void guardaUtentes(Utente *ordena[], FILE *saida, int n) { int i; /* Escreve utentes: */ for(i = 0; i < n; i++) { fprintf(saida, "%s\n", ordena[i]->nome); fprintf(saida, "%d\n", ordena[i]->categoria); fprintf(saida, "%d\n", ordena[i]->codigo); } /* Verifica se houve erros de escrita: */ if(ferror(saida)) { fprintf(stderr, "Erro: escrevendo no ficheiro!\n"); exit(EXIT_FAILURE); } } /* Note-se a utilizacao da ordenacao por permutacao (em ingles "bubble sort") */ void ordenaUtentes(Utente *ponteiros[], int usaNome, int n) { Utente *temp; int topo, limite, i; topo = n - 1; /* Por uma questao de eficiencia repete-se o codigo de ordenacao: */ if(usaNome) do { limite = topo; topo = 0; for(i = 0; i < limite; i++) if(strcmp(ponteiros[i]->nome, ponteiros[i+1]->nome) > 0) { temp = ponteiros[i]; ponteiros[i] = ponteiros[i+1]; ponteiros[i+1] = temp; topo = i; } } while(topo != 0); else do { limite = topo; topo = 0; for(i = 0; i < limite; i++) if(ponteiros[i]->codigo > ponteiros[i+1]->codigo) { temp = ponteiros[i]; ponteiros[i] = ponteiros[i+1]; ponteiros[i+1] = temp; topo = i; } } while(topo != 0); } /* Programa principal: */ int main(int argc, char *argv[]) { Utente utentes[UTENTES_MAX]; Utente *ponteiros[UTENTES_MAX]; int usaNome, i, n; FILE *entrada, *saida; if(argc > 4) { fprintf(stderr, "Numero de argumentos invalido.\n" "%s [entrada [saida [nome/codigo]]]\n", argv[0]); return EXIT_FAILURE; } /* Valores por omissao: */ entrada = stdin; saida = stdout; usaNome = 1; /* Le opcoes e abre ficheiros: */ switch(argc) { case 4: if(strcmp(argv[3], "nome") == 0) usaNome = 1; else if(strcmp(argv[3], "codigo") == 0) usaNome = 0; else { fprintf(stderr, "Argumento 3 invalido!\n"); return EXIT_FAILURE; } case 3: if((saida = fopen(argv[2], "w")) == 0) { fprintf(stderr, "Erro criando o ficheiro \"%s\".\n", argv[2]); return EXIT_FAILURE; } case 2: if((entrada = fopen(argv[1], "r")) == 0) { fprintf(stderr, "Erro abrindo o ficheiro \"%s\".\n", argv[1]); return EXIT_FAILURE; } default: break; } /* Ler ficheiro: */ n = leUtentes(utentes, entrada); /* Ordena utentes: */ for(i = 0; i < n; i++) ponteiros[i] = &utentes[i]; ordenaUtentes(ponteiros, usaNome, n); /* Guarda utentes: */ guardaUtentes(ponteiros, saida, n); /* Fecha ficheiros: */ switch(argc) { case 4: case 3: fclose(saida); case 2: fclose(entrada); default: break; } return EXIT_SUCCESS; }