// Text zeilenweise sortieren (qsort), von stdin nach stdout
// 
// Aufruf: textsort
// 
// Klaus Kusche, 2010

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

// Max. Zeilenlänge der eingelesenen Zeilen (incl. \n\0) 
// Nicht zu groß, weil wir ja MAX_LINES viele Strings dieser Größe anlegen! 
#define MAX_LEN 82
// Max. Anzahl der Zeilen
#define MAX_LINES 100

int lineCmp(const void *p1, const void *p2);

// Vergleichsfunktion für qsort
// p1 und p2 zeigen auf die zu vergleichenden Elemente des Arrays "lines"
// Diese Elemente sind Zeilen, also char-Arrays,
// daher sind p1 und p2 eigentlich "Pointer auf char"
// und die Zeilentexte, auf die sie zeigen, müssen verglichen werden
int lineCmp(const void *p1, const void *p2)
{
// Möglichkeit 1:
  //const char *z1 = (const char *) p1;
  //const char *z2 = (const char *) p2;
  //return strcmp(z1, z2);

// Möglichkeit 2:
  return strcmp((const char *) p1, (const char *) p2);
}

int main(int argc, const char *argv[])
{
  if (argc != 1) {
    fprintf(stderr, "Aufruf: %s\n", argv[0]);
    exit(EXIT_FAILURE);
  }

  char lines[MAX_LINES][MAX_LEN];  // Fixes Array von Strings fixer Größe
  int lineCnt;                     // Anzahl der belegten Zeilen in lines

  // Input zeilenweise verarbeiten bis der File zu Ende ist, mitzählen
  for (lineCnt = 0; ; ++lineCnt) {
    if (lineCnt == MAX_LINES) {
      fprintf(stderr, "%s: Limit of %d lines exceeded\n", argv[0], MAX_LINES);
      exit(EXIT_FAILURE);
    }

    // Lies eine Zeile und speichere sie in der Zeile lineCnt des 2-dim Arrays
    if (fgets(lines[lineCnt], sizeof(lines[lineCnt]), stdin)
        == NULL) {
      // Input ist zu Ende
      break;      
    }

    if (strchr(lines[lineCnt], '\n') == NULL) {
      // Eingelesene Zeile enthält kein \n
      // ==> passiert nur, wenn kein Platz mehr für das \n war
      // ==> Zeile ist länger als MAX_LEN Zeichen
      // Problem unter Windows:
      // Letzte Zeile von Textfiles hat oft kein \n ==> falsche Fehlermeldung!
      // (in Linux hat auch die letzte Zeile immer ein \n)
      fprintf(stderr, "%s: Incomplete line %d\n", argv[0], lineCnt + 1);
      exit(EXIT_FAILURE);
    }
  }

  // sortieren, Elementgröße = Größe einer Zeile des 2-dim Arrays
  qsort(lines, lineCnt, sizeof(lines[0]), lineCmp);

  // zeilenweise ausgeben
  for (int i = 0; i < lineCnt; ++i) {
    fputs(lines[i], stdout);
  }
  
  exit(EXIT_SUCCESS);
}
