Napisati C program koji leksikografski sortira u neopadajućem poretku linije sa ulaza. Ako je kao argument komandne linije zadat opcioni argument -n , onda izvršiti numeričko sortiranje. Ako je kao argument komandne linije zadat opcioni argument -r , onda promeniti redosled sortiranja u nerastući poredak. Program treba da radi sa preusmeravanjem standardnog ulaza, a svoj rezultat treba da upiše u datoteku sortiran.dat. Obezbediti da program radi i kad su prisutna oba opciona argumenta -r -n . Poruke o greškama ispisati na standardni izlaz za poruke o grešci. Može se pretpostaviti da ukupan broj linija nije veći od 1000, kao i da dužina svake linije nije veća od 80 karaktera. #include #include #include #define TRUE 1 #define FALSE 0 #define MAXLINES 1000 /* max broj linija */ char *lineptr[MAXLINES]; /* pokazivaci na linije sa ulaza*/ #define MAXLEN 81 /* max duzina linije */ int reverse = FALSE; /* indikator pojave opcionog argumenta ?r */ /* getline: ucitava liniju i vraca njenu duzinu*/ int getline(char s[], int lim) { int c; /* znak sa ulaza*/ int i; /* brojac u petlji */ for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; i++) s[i] = c; if (c == '\n') { s[i++] = c; } s[i] = '\0'; return i; } /* readlines: ucitavanje ulaznih linija limitirane duzine */ /* vraca broj ucitanih linija < maxlines ili -1 u slucaju preobimnog ulaza*/ int readlines(char *lineptr[], int maxlines) { int len, nlines; /* duzina linije, broj ucitanih linija sa ulaza*/ char *p, line[MAXLEN]; nlines = 0; while ((len = getline(line, MAXLEN)) > 0) if (nlines >= maxlines || (p = malloc(len)) == NULL) return -1; /* preobiman ulaz*/ else { line[len - 1] = '\0'; /* izbaci novi red */ strcpy(p, line); lineptr[nlines++] = p; } return nlines; } /* writelines: upis linija u datoteku */ void writelines(char *lineptr[], int nlines) { int i; FILE *f; f= fopen ("sortiran.dat", "w"); if (!f) { fprintf(stderr, "Neuspelo otvaranje datoteke sortiran.dat\n"); exit(EXIT_FAILURE); } for (i = 0; i < nlines; i++) fprintf(f, "%s\n", lineptr[i]); fclose (f); } /* poredjenje niski; funkcija se stara i o poredjenju niski u slucaju da je prisutan opcioni argument -r */ int pstrcmp(const void *p1, const void *p2) { char * const *s1 = reverse ? p2 : p1; char * const *s2 = reverse ? p1 : p2; return strcmp(*s1, *s2); } /* numcmp: poredi numercki dve niske */ int numcmp(const void *p1, const void *p2) { char * const *s1 = reverse ? p2 : p1; char * const *s2 = reverse ? p1 : p2; double v1, v2; v1 = atof(*s1); v2 = atof(*s2); if (v1 < v2) return -1; else if (v1 > v2) return 1; else return 0; } int main(int argc, char *argv[]) { int nlines; /*broj ucitanih linija na ulazu*/ int numeric = FALSE; /* indikator pojave opcionog argumenta -n */ int i,j; /* brojaci u petlji */ /* test prisustva bilo kog opcionog argumenta */ /* u slucaju da opcioni argumenti nisu prisutni, sortiranje je leksikografsko u neopadajucem poretku */ /*prosledjivanje argumenata komandne linije */ for (i = 1; i < argc && argv[i][0] == '-'; i++) { /*prosledjivanje opcija za reverzno ili/i numericko sortiranje*/ for (j=1; argv[i][j] !='\0'; j++) { /* test prisustva opcionih argumenata -n, -r */ switch (argv[i][j]) { case 'n': numeric = TRUE; break; case 'r': reverse = TRUE; break; default: fprintf(stderr, "Nekorektan opcioni argument '%s'\n", argv[i]); return EXIT_FAILURE; } } } /* ucitavanje linija sa ulaza*/ if ((nlines = readlines(lineptr, MAXLINES)) >= 0) { /* u slucaju uspesnog ucitavanja linija sa ulaza, vrsi se odgovarajuce sortiranje, prema zahtevima - numericko ili leksikografsko, neopadajuce ili nerastuce*/ qsort(lineptr, nlines, sizeof(*lineptr), numeric ? numcmp : pstrcmp); /* upis rezulata sortiranja u datoteku */ writelines(lineptr, nlines); return EXIT_SUCCESS; } else { fputs("Preobiman ulaz za sortiranje\n", stderr); return EXIT_FAILURE; } }