#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;
}