Universität Ulm, Fakultät für Mathematik und Wirtschaftswissenschaften, SAI

Lösung zu Blatt 11 der Systemnahe Software I (WS 97/98)

16 Namenslisten

qsort.c

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

/* Struktur fuer Namen - Zerlegung nur einmal notwendig. */
typedef struct name *namesPtr;
typedef struct name { char *first, *last; } names;

/* Vergleichsfunktion fuer qsort */
static int intcompare(namesPtr i, namesPtr j) {
   if (!strcmp(i->last, j->last)) return strcmp(i->first, j->first);
   else return strcmp(i->last, j->last);
}

void main(int argc, char *argv[]) {
   namesPtr p;
   char *inp, *l;
   int i = 0, lenf, lenl, size = 0, max = 2;
   FILE *infile, *outfile;
   switch (argc) {
      case 1: /* Kein Parameter - also stdin und stdout */
	 infile = stdin;
	 outfile = stdout;
	 break;
      case 2: /* Aendere Eingabe */
	 infile = fopen(argv[1], "r");
	 outfile = stdout;
	 break;
      case 3: /* Andere Ein- und Ausgabe */
	 infile = fopen(argv[1], "r");
	 outfile = fopen(argv[2], "w");
	 break;
      default: /* Mehr als 2 Parameter - das geht nur wirklich nicht */
	 fprintf(stderr,"USE: %s [infile [outfile]]\n", argv[0]);
	 exit(1);
	 break;
   }
   p = (namesPtr)calloc(max, sizeof(names)); /* Speicher holen */
   inp = (char *)calloc(80, sizeof(char));
   if (!p) perror("calloc");
   while (fscanf(infile, " %[^\n]", inp) > 0) {
      if (size == max) { /* Mehr Speicher wird benoetigt */
	 max <<= 1;
	 p = realloc(p, max * sizeof(names)); /* Verdopple Speicher */
	 if (!p) perror("realloc"); /* I hope it did not happen on turing */
      }
      l = (char *)strrchr(inp, ' ') + 1;
      lenl = strlen(l);                /* Laenge Nachname */
      lenf = strlen(inp) - lenl -1;    /* Laenge Vorname  */
      (p + size)->first = (char *)calloc(lenf + 1, sizeof(char));
      (p + size)->last = (char *)calloc(lenl + 1, sizeof(char));
      strncpy((p + size)->first, inp, lenf); /* Kopiere Vorname in Struktur */
      strcpy((p + size)->last, inp + lenf + 1);
      size++;
   }
   qsort(p, size, sizeof(names), (void *)intcompare); /* Sortiere */
   for (i = 0; i < size; i++) /* Und die Ausgabe */
      fprintf(outfile, "%s %s\n", (p + i)->first, (p + i)->last);
   free(p); free(inp);        /* Speicher freiraeumen */
   fclose(infile);
   fclose(outfile);
   exit(0);
}

Universität Fakultät SAI

Ingo Melzer, 26. January 1998