Napisati C program koji ce poslednjih n linija datoteke prva.dat ispisati na standardni izlaz sortirane po poslednjoj reci. Broj linija nije unapred poznat. Svaka linija sadrzi ne više od 80 karaktera, a svaka rec pripada tacno jednoj liniji. Prirodan broj n se zadaje kao argument komandne linije. Sortiranje izvršiti u u neopadajucem leksikografskom poretku , sem ako kao opcioni argument komandne linije nije zadata opcija -r, u kom slucaju izvršiti sortiranje u nerastucem leksikografskom poretku. Poruke o nekorektnim parametrima komandne linije ispisati na standardnom izlazu za poruke o grešci. Program mora biti osetljiv na razliku malih i velikih slova. Pri sortiranju koristiti funkciju qsort iz standardne biblioteke. #include < stdio.h> #include < stdlib.h> #include < string.h> #include < ctype.h> #define LINELIMIT 71 void uzmirec (char *linija, char *rec); int uporedi1(const void *a,const void *b); /*poredjenje linija */ int uporedi2(const void *a,const void *b); /*poredjenje linija */ void greska (char *tekst, char *opc); /* ispis teksta greske u kom. liniji sa pogr. opcijom */ int reverse=0; /*glavni program */ main(int argc,char *argv[]) { FILE *in; int kolicina; /* broj linija za prepis */ char* line; /* pokazivac na liniju */ char ** linepok; /* na linije */ int CountLine; /* brojac linija do kolicine */ int j; /*brojacka promenljiva */ int kraca; /*ukazuje da n prevailazi duzinu datoteke*/ /*ucitavanje broja linija koji ce se prepisati i detektovanje greske medju arg. kom. linije*/ if (argc < 2) greska("Nekorektan poziv programa", argv[0]); else if (argc==2) if (isdigit(argv[1][0]) ) sscanf( argv[1], "%d", &kolicina ); else greska("Nekorektan broj linija", argv[1] ); else if (argc >2) { if (isdigit(argv[1][0]) ) {sscanf( argv[1], "%d", &kolicina ); if (strcmp(argv[2], "-r")) greska("Nekorektna opcija",argv[2]); else reverse=1; } else if (!strcmp(argv[1], "-r")) {reverse=1; if (isdigit(argv[2][0]) ) sscanf( argv[2], "%d", &kolicina ); else greska("Nekorektan parametar", argv[2]); } else greska("Nekorektna opcija", argv[1]); if (argc >3) printf("\nIgnorise se visak parametara kom. linije\n"); } /* alociranje niza pokazivaca linija */ linepok = (char **) calloc(kolicina+1, sizeof(char*)); if( linepok == NULL ) { fprintf(stderr, "ne moze da se alocira prostor \n"); exit(1);} if( (in=fopen("ulaz.txt","r")) == NULL ) { fprintf(stderr, "ulaz.txt ne moze da se otvori za citanje \n"); exit(1);} for( j = 0; j < kolicina+1; j++ ) { linepok[j] = (char *) malloc( LINELIMIT*sizeof(char) ); if( linepok[j] == NULL ) { fprintf(stderr, "ne moze da se alocira prostor \n"); exit(3);} } CountLine = 0; kraca=1; /*prepis linija */ while( 1) { if (CountLine==kolicina+1) /*kako sada niz pokazivaca sadrzi poslednjih n+1 linija*/ { for (j=0;j < kolicina;j++) strcpy(linepok[j],linepok[j+1]); /*ucitanih do sada,to uklanjamo sadrzaj 1.clan tog niza */ CountLine=kolicina; kraca=0; /*ulazna datoteka ima ne manje od n linija*/ } if ( fgets( line, LINELIMIT,in) == NULL )break; /*uzeta je sledeca linija i testiran kraj linija */ strcpy(linepok[CountLine],line); /*cuvanje tekuce linije u nizu od n linija */ CountLine ++; } if (kraca) kolicina=CountLine; /*ako je datoteka kraca od n linija*/ /*onda kolicina linija koja se prepisuje i sortira je jednaka broju ucitanih */ if (reverse) qsort(linepok, kolicina, sizeof(linepok[0]), &uporedi2); else qsort(linepok, kolicina, sizeof(linepok[0]), &uporedi1); /* prepis linija na standardni izlaz*/ for( j=0;j < kolicina;j++ ) printf("%s",linepok[j]); /*oslobadjanje zauzetog prostora za niz pokazivaca linija */ for(j=0;j< = kolicina; j++ ) free(linepok[j]); free(linepok); fclose(in); return 0; } int uporedi1(const void *a,const void *b) { char s1[LINELIMIT], s2[LINELIMIT]; char *l1= *(char **)a; char *l2= *(char **)b; uzmirec(l1,s1); uzmirec(l2,s2); return strcmp(s1, s2); } int uporedi2(const void *a,const void *b) { return (-1)*uporedi1(a, b); } void uzmirec (char *linija, char *rec) { int k=0, j=0; while (isspace(linija[k]) && linija[k]!='\0') k++; while (linija[k]!=' ' && linija[k]!='\t' && linija[k]!='\n' && linija[k]!='\0') {rec[j]=linija[k]; k++; j++;} rec[j]='\0'; } void greska (char *tekst, char *opc) { fprintf(stderr,"\nGreska: %s %s\n", tekst, opc); exit(3); }