Programarea Calculatoarelor 2 - Laborator 9

Implementați programul sort care sortează liniile de text citite de la intrarea standard și le afișează în ordine la ieșirea standard. Programul acceptă pe linia de comandă combinații ale următoarelor opțiuni: De exemplu, dacă liniile de la intrare au conținutul
Nume,Prenume,Media
atunci sort -k1 -t, va sorta liniile alfabetic după nume, iar sort -t, -n -k3 le va sorta în ordine crescătoare a mediilor.

Indicații: Pentru sortarea propriu-zisă se va folosi funcția standard qsort (declarată în stdlib.h), pentru care se vor scrie funcțiile de comparație necesare.
Pentru despărțirea în câmpuri puteți folosi repetat funcția strchr (declarată în string.h).
Pentru conversia numerică, puteți folosi funcția strtod (declarată în string.h).
Programul va citi în memorie întregul conținut de sortat, până la EOF. (Tehnici de sortare externă vor fi discutate la cursul de algoritmi). Numărul de linii de sortat nu va fi limitat dinainte; se va aloca dinamic un tablou și la nevoie se va realoca crescându-i dimensiunea. Lungimea unei linii e preferabil să nu fie limitată nici ea; se poate folosi funcția getline (rescrisă aici cu fgets față de varianta de la curs).
Considerați la alegere dacă sfărșitul de linie (caracterul '\n') face parte efectiv din linie la sortare sau nu. (Multe programe de sortat consideră că nu, unele standarde mai vechi da). La sortarea numerică, puteți considera că se ordonează întâi liniile care pe câmpul respectiv de fapt nu conțin numere.
Pentru a evita prelucrarea unei linii de fiecare dată când ea este comparată (căutarea câmpului; eventuala convertire în format numeric, etc.), se poate încerca prelucrarea prealabilă a fiecărei linii, după opțiunile date pe linia de comandă. Pentru aceasta, s-ar putea reține pentru fiecare linie o structură care conține un pointer la line și un câmp cu cheia de sortare. Aceasta la rândul ei ar putea fi o uniune care conține fie un număr real (convertit din reprezentarea textuală), fie informații despre cămpul după care se sortează alfabetic (de exemplu pointerul de început și lungimea). Funcțiile de comparare ar lucra cu structurile astfel definite.
(Opțional) Ca o variantă posibil mai eficientă de lucru cu memoria, încercați citirea cu fread (de ex. pe blocuri multipli de un sector), și parcurgerea ulterioară pentru a determina pozițiile de sfârșit de linie. (Acestea ar putea fi înlocuite în memorie cu '\0', mai ales dacă programul nu consideră '\n' ca fiind parte din linie la sortare).
(Studiu opțional) Pentru comentarii despre eficiența conversiei numerice, citiți cu info sort documentația mai detaliată pentru opțiunile -g și -n. Gândiți-vă cum ați implementa o funcție care compară două numere (întregi sau reale) fără conversie, folosind direct reprezentarea lor externă ca șiruri, chiar și pentru "numere lungi", care depășesc precizia de memorare a tipurilor numerice standard.


Marius Minea
Last modified: Wed Dec 3 00:29:03 EET 2003