|
[ ___ @ 11.05.2011. 17:18 ] @
| Zadatak glasi ovako:
* U datoteci pesme.txt nalaze se informacije o gledanosti pesama na Youtube-u u sledecem formatu: izvodjac - naslov, brojGledanja
* Napisati program koji ucitava informacije o pesmama i vrsi sortiranje pesama u zavisnosti od argumenata komandne linije:
* (a) nema opcija, sortiranje po broju gledanja.
* (b) -i, sortiranje po imenu izvodaca
* (c) -n, sortiranje po naslovu pesme
* Ne praviti nikakve pretpostavke o maksimalnoj duzini imena izvodjaca, naslova pesme, kao i ukupnom broju pesama.
Da li mi neko može dati savet kako da dinamički alociram ove niske, ime izvođača i naziv pesme? Postaviću dole kod, ali on funkcioniše samo ako se navedu ograničenja u dužini ta dva podatka :(
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// broj elemenata koje rezervisemo unapred
#define KORAK 10
// struktura Pesme
typedef struct {
char* izvodjac;
char* naslov;
int brGledanja;
} Pesme;
// pomocni karakter, globalna promenljiva u kojoj se cuva opcija koju je korisnik naveo
char kriterijum;
// samo prototip funkcije, telo se nalazi ispod glavne
int uporedi(const void*, const void*);
int main(int argc, char** argv) {
// brojaci
int i, j;
// pomocna promenljiva za iscitavanje niski iz datoteke
char s[50];
// ucitavanje podataka iz datoteke, i smestanje u niz struktura Pesme
FILE* ulaz;
if((ulaz = fopen("pesme.txt", "r")) == NULL) {
printf("Greska pri ucitavanju datoteke.\n");
exit(1);
}
// rezervisemo mesta za jednu strukturu Pesme
Pesme* pesme = (Pesme*) malloc(sizeof(Pesme));
if(pesme == NULL) {
printf("Greska pri alokaciji.\n");
exit(1);
}
// broj (unetih) elemenata u nizu struktura
int n = 0;
// broj alociranih struktura u memoriji
int alocirano = 1;
while(1) {
// ako je broj alociranih jednak broju unetih struktura, alociramo jos prostora
if(alocirano == n) {
alocirano+=KORAK;
pesme = (Pesme*)realloc(pesme, sizeof(Pesme)*alocirano);
// i naravno, obavezna provera da li je alokacija memorije uspesno izvrsena
if(pesme == NULL) {
printf("Greska pri alokaciji.\n");
exit(1);
}
}
// ako procitamo prazan red, dosli smo do kraja datoteke, i naslino izlazimo iz petlje
if(fgets(s,50,ulaz) == NULL) break;
// sada u niski s cuvamo liniju iz datoteke, a ona je formata " ime_autora ili/i_prezime_odnosno_pseudonim_autora - naziv_pesme, 123456789 "
// ime autora citamo do prve povlake, s tim sto se vratimo jedan karakter unazad, i tu nalepimo nulu (da ne bismo cuvali belinu)
// koristimo dva brojaca, i i j, sa i se krecemo po liniji iz datoteke, a sa j po odredjenom podatku strukture
for(i=0,j=0;s[i]!='-';i++,j++)
pesme[n].izvodjac[j] = s[i];
pesme[n].izvodjac[j-1] = '\0';
// naziv pesme ucitavamo od i (koje cuva karakter kod kog smo stali sa citanjem) pa jos dva karaktera desno, do zareza
for(i=i+2,j=0;s[i]!=',';i++,j++)
pesme[n].naslov[j] = s[i];
pesme[n].naslov[j-1] = '\0';
// sada smo na itoj poziciji, ali krecemo sa citanjem od i+2 da ne bismo ucitali zarez i belinu
// koristim pomocnu nisku pom, u kojoj cu cuvati broj u obliku niske
char pom[20];
pesme[n].brGledanja = 0;
for(i=i+2, j=0;s[i]!='\n';i++, j++)
pom[j] = s[i];
pom[j] = '\0';
pesme[n].brGledanja = atoi(pom);
n++;
}
// kriterijum po default vrednosti neka stoji na b; u slucaju da je unesena opcija, dolazi do izmene
kriterijum = 'b';
if(strcmp(argv[1],"-i") == 0 || strcmp(argv[1], "-n") == 0)
kriterijum = argv[1][1];
// kriterijum se cuva u globalnoj promenljivoj, tako da funkcija uporedi na osnovu njega vraca odgovarajucu vrednost
qsort(pesme, n, sizeof(Pesme), &uporedi);
// ispisujemo sortiran niz struktura
for(i=0;i<n;i++)
printf("%s - %s, %d\n", pesme[i].izvodjac, pesme[i].naslov, pesme[i].brGledanja);
// oslobadjamo alociranu memoriju
free(pesme);
// zatvaramo datoteku
fclose(ulaz);
// saljemo informaciju o uspesnom izvrsavanju programa. the end.
return 0;
}
int uporedi(const void* pPesma1, const void* pPesma2) {
Pesme Pesma1 = *(Pesme*)pPesma1;
Pesme Pesma2 = *(Pesme*)pPesma2;
if(kriterijum == 'i')
return strcmp(Pesma1.izvodjac, Pesma2.izvodjac);
if(kriterijum == 'n')
return strcmp(Pesma1.naslov, Pesma2.naslov);
return Pesma1.brGledanja - Pesma2.brGledanja;
}
|
[ ___ @ 11.05.2011. 22:55 ] @
Rešen problem...
[ Sonec @ 15.05.2011. 17:44 ] @
Evo ovde celokupan kod
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
char *izvodjac;
char *naslov;
int brGledanja;
}pesma;
char tip;
int poredi(const void *a, const void *b)
{
pesma p1 = *(pesma*)a;
pesma p2 = *(pesma*)b;
if(tip == 'b')
return p1.brGledanja - p2.brGledanja;
else if(tip == 'i')
return strcmp(p1.izvodjac, p2.izvodjac);
else if(tip == 'n')
return strcmp(p1.naslov, p2.naslov);
}
char* ucitaj_nisku(FILE *f)
{
char c, *r = NULL;
int n = 0;
if(feof(f))
return NULL;
c = fgetc(f);
while(c != ' ' && c != EOF)
{
if(c == '\n')
{
c = fgetc(f);
continue;
}
n++;
r = realloc(r, sizeof(char) * n);
if(r == NULL)
{
printf("greska");
exit(EXIT_FAILURE);
}
r[n - 1] = c;
c = fgetc(f);
}
n++;
r = realloc(r, sizeof(char) * n);
if(r == NULL)
{
printf("greska");
exit(EXIT_FAILURE);
}
r[n - 1] = 0;
return r;
}
int main(int argc, char *argv[])
{
pesma *pesme;
FILE *f;
char pom1[1000], pom2[1000], p[10], *r1, *r2, *r3;
int pom3, n, i, uspesno_citanje;
f = fopen("pesme.txt", "r");
if(f == NULL)
{
printf("Greska");
exit(EXIT_FAILURE);
}
n = 0;
pesme = NULL;
uspesno_citanje = 1;
while(uspesno_citanje)
{
r1 = ucitaj_nisku(f);
r2 = ucitaj_nisku(f);
r3 = ucitaj_nisku(f);
if(r1 == NULL || r2 == NULL
|| r3 == NULL
|| fscanf(f, "%d", &pom3) != 1)
{
uspesno_citanje = 0;
continue;
}
n++;
pesme = (pesma*)realloc(pesme, n * sizeof(pesma));
if(pesme == NULL)
{
printf("Greska");
exit(EXIT_FAILURE);
}
r3[strlen(r3) - 1] = 0;
pesme[n - 1].brGledanja = pom3;
pesme[n - 1].izvodjac
= (char*)malloc((strlen(r1) + 1) * sizeof(char));
pesme[n - 1].naslov
= (char*)malloc((strlen(r3) + 1) * sizeof(char));
if(pesme[n - 1].izvodjac == NULL
|| pesme[n - 1].naslov == NULL)
{
printf("Greska");
exit(EXIT_FAILURE);
}
strcpy(pesme[n - 1].izvodjac, r1);
strcpy(pesme[n - 1].naslov, r3);
free(r1);
free(r2);
free(r3);
}
/*while(fscanf(f, "%s%s%s%d",
pom1, p, pom2, &pom3) == 4)
{
n++;
pesme = (pesma*)realloc(pesme, n * sizeof(pesma));
if(pesme == NULL)
{
printf("Greska");
exit(EXIT_FAILURE);
}
pom2[strlen(pom2) - 1] = 0;
pesme[n - 1].brGledanja = pom3;
pesme[n - 1].izvodjac
= (char*)malloc((strlen(pom1) + 1) * sizeof(char));
pesme[n - 1].naslov
= (char*)malloc((strlen(pom2) + 1) * sizeof(char));
if(pesme[n - 1].izvodjac == NULL
|| pesme[n - 1].naslov == NULL)
{
printf("Greska");
exit(EXIT_FAILURE);
}
strcpy(pesme[n - 1].izvodjac, pom1);
strcpy(pesme[n - 1].naslov, pom2);
}*/
fclose(f);
if(argc == 1)
{
tip = 'b';
}
else if(argc == 2)
{
tip = argv[1][1];
}
else
{
printf("greska");
}
qsort(pesme, n, sizeof(pesma), &poredi);
for(i = 0; i < n; i++)
printf("%s %s %d\n"
, pesme[i].izvodjac
, pesme[i].naslov
, pesme[i].brGledanja);
for(i = 0; i < n; i++)
{
free(pesme[i].izvodjac);
free(pesme[i].naslov);
}
free(pesme);
system("PAUSE");
return 0;
}
Datoteka je "pesme.txt" i moze da izgleda npr. ovako:
Code:
izvodjac1 - naslov1, 5
izvodjac2 - naslov2, 4
izvodjac3 - naslov3, 7
izvodjac4 - naslov4, 2
izvodjac5 - naslov5, 9
izvodjac6 - naslov6, 6
Inace kod nije moj, al sam postavio da vide ljudi, ako nekoga zanima...
P.S Pozdrav kolega sa faxa!
[ ___ @ 15.05.2011. 18:23 ] @
Zahvaljujem :) rešila sam na kraju, do duše drugačije :)
[ Sonec @ 15.05.2011. 19:17 ] @
Kod je odavde http://www.matf.bg.ac.rs/p/dje...-dinamicka-alokacija-memorije/
Ja sam iz 1o4B, nije ovo moj asistent, vec od 1o4A, al rece mi drug iz 1o4A da je njima asistent pokazao kako se radi.....
Mogla bi i ti tvoj "nov" kod da postavis, cisto da vidim ideju, ako ti nije frka...
P.S Izvinjavam se na spemu, al koleginica mi je poslala privatnu poruku, a posto nisam clan vise od 7 dana, moram ovako da joj odgovorim.
[ Intex @ 02.07.2011. 23:18 ] @
U pitanju je unija dva skupa, A i B, pise se u C koji se u toku rada relocira. Nikako na izlazu da dobijem ok rezultat.
Code: #include <stdio.h>
#include <stdlib.h>
int main() {
int *A, *B, *C;
int i, j, k=0, n1, p, n2, n3;
printf("Unwsite dimenzije nizova A i B: \n");
scanf("%d%d", &n1, &n2);
A=(int*)malloc(n1*sizeof(int));
B=(int*)malloc(n2*sizeof(int));
printf("\n Unesite elemente niza A:");
for(i=0;i<n1;i++) {
printf("\n %d. element: ", i+1);
scanf("%d", &A[i]); }
printf("\n Unesite elemente niza B:");
for(i=0;i<n2;i++) {
printf("\n %d. element: ", i+1);
scanf("%d", &B[i]); }
C=(int*)malloc((n1+n2)*sizeof(int));
for(i=0;i<n1;i++)
C[i]=A[i];
for(i=0;i<(n1+n2);i++)
if(A[i]!=B[i]) {
for(j=n1;j<(n1+n2);j++)
C[j]=B[i];
k++; }
p=n1+k;
C=(int*)realloc(C, p*sizeof(int));
printf("\n Elementi skupa c su: ");
for(i=0;i<k;i++) {
printf("\n %d. element niza je: %d .", i+1, C[i]);
}
system("PAUSE");
return 0;
}
[ Mihajlo Cvetanović @ 04.07.2011. 09:02 ] @
Prvo što bode oči je "%d%d" prilikom čitanja dva broja. Stavi neki spejs između, "%d %d". Ako to nije rešenje onda nam daj više informacija. Šta imaš kao ulazne podatke, šta očekuješ kao izlazne, a šta zapravo dobiješ na izlazu?
[ Intex @ 04.07.2011. 14:09 ] @
To čitanje dva broja radi i tako. Program treba da nadje uniju dva dinamički alocirana niza i prebaci ih u novi, takođe dinamički alociran niz, koji se na kraju relocira. Konkretno, problem je u petlji koja treba da kopira elemente iz B niza, kojih nema u A nizu, u C niz.
[ Picsel @ 04.07.2011. 16:05 ] @
Umesto
Code: for(i=0;i<(n1+n2);i++)
if(A[i]!=B[i]) {
for(j=n1;j<(n1+n2);j++)
C[j]=B[i];
k++; }
trebalo bi nesto ovako
Code: for (i=0; i<n2; i++)
{
int vecPostoji=0;
for (j=0; j<n1; j++)
if (B[i]==A[j])
{
vecPostoji=1;
break;
}
if (!vecPostoji)
{
C[n1+k]=B[i];
k++;
}
}
[ Intex @ 05.07.2011. 21:29 ] @
Nisam baš uspeo da uklopim ovu petlju u program, i nije mi baš nešto naročito jasna... :/
[ Picsel @ 05.07.2011. 22:49 ] @
Potrebno je i izmeniti Code: for(i=0;i<k;i++) {
printf("\n %d. element niza je: %d .", i+1, C[i]);
}
i staviti
Code: for(i=0;i<p;i++) {
printf("\n %d. element niza je: %d .", i+1, C[i]);
}
Ceo program bi tad izgledao ovako
Code: #include <stdio.h>
#include <stdlib.h>
int main() {
int *A, *B, *C;
int i, j, k=0, n1, p, n2, n3;
printf("Unwsite dimenzije nizova A i B: \n");
scanf("%d%d", &n1, &n2);
A=(int*)malloc(n1*sizeof(int));
B=(int*)malloc(n2*sizeof(int));
printf("\n Unesite elemente niza A:");
for(i=0;i<n1;i++) {
printf("\n %d. element: ", i+1);
scanf("%d", &A[i]); }
printf("\n Unesite elemente niza B:");
for(i=0;i<n2;i++) {
printf("\n %d. element: ", i+1);
scanf("%d", &B[i]); }
C=(int*)malloc((n1+n2)*sizeof(int));
for(i=0;i<n1;i++)
C[i]=A[i];
for (i=0; i<n2; i++)
{
int vecPostoji=0;
for (j=0; j<n1; j++)
if (B[i]==A[j])
{
vecPostoji=1;
break;
}
if (!vecPostoji)
{
C[n1+k]=B[i];
k++;
}
}
p=n1+k;
C=(int*)realloc(C, p*sizeof(int));
printf("\n Elementi skupa c su: ");
for(i=0;i<p;i++) {
printf("\n %d. element niza je: %d .", i+1, C[i]);
}
system("PAUSE");
return 0;
}
Sto se tice petlje koja je nejasna - Pre te petlje u C se stave svi clanovi niza A. Zatim se redom prolazi kroz niz B. Za trenutni clan niza B, postavi se 'vecPostoji' flag na 0, koji oznacava da tog elementa nema u skupu A. Zatim se sa for (j=0; j<n1; j++) petljom prolazi kroz niz A i poredi se da li se taj trenutni clan u nizu B nalazi u nizu A. Ako se nalazi, postavlja se 'vecPostoji' na 1 i iskace se iz petlje. Na kraju, proverava se da li smo taj trenutni clan niza B nasli u skupu A (pomocu 'vecPostoji') i ako nismo, dodaje se na zacelje niza C (na n1+k-to mesto, gde je k brojac koji oznacava koliko je clanova niza B dodato u C).
[ Intex @ 06.07.2011. 18:01 ] @
Ok, hvala, lepo je resenje. U medjuvremenu sam nasao jos jedno resenje, ali i ovo je skroz ok. 
Copyright (C) 2001-2025 by www.elitesecurity.org. All rights reserved.
|