C

matix

Fizikalc
22. jul 2007
2.132
0
36
35
No, pa so nam na faksu podturili še c.. ki se mi zdi skrajno butast (dajte, da me en bo zdaj kdo napadel zaradi te izjave
grin1.gif
), glede na to, da smo prej delali v Javi, kjer znam že marsikaj.. v glavnem, za rešit imam sledečo nalogo:

Napiši program, ki zna preveriti ali je podano besedilo pravilno oblikovan dokument XML. Besedilo naj bo zapisano v datoteki, katere
ime podamo programu v ukazni vrstici ob zagonu. Besedilo predstavlja pravilno oblikovan dokument XML, če velja naslednje:

1. besedilo XML je sestavljeno iz elementov XML, ki so sestavljeni iz začetne oznake XML, ustrezne zaključne oznake XML, med obema pa se lahko nahaja ena ali več oznak XML oziroma besedilo poljubne dolžine:

<oseba>
<ime>Peter</ime>
<priimek>Pan</priimek>
</oseba>
2. element XML brez vsebine, je lahko zapisan na skrajšan način:

<brezStatusa />
ali

<brezStatusa/>
3. oznaka XML lahko vsebuje dodatne atribute v obliki atribut="vrednost":

<sestavina kolicina="3" enota="kilogram">moka</sestavina>
4. besedilo XML lahko vsebuje le en vrhnji element XML.

Ostale prvine dokumenta XML, kot sta deklaracija in komentarji, lahko zanemarite. Oznake XML so lahko ugnezdene, ne smejo pa se križati. Preverjanje pravilnosti oznak izvedite s skladom, ki hrani trenutno veljavne oznake. Sklad implementirajte dinamično s kazalci.



Matrajo me dve reči:

1.
Citat:
<sestavina kolicina="3" enota="kilogram">moka</sestavina>
4. besedilo XML lahko vsebuje le en vrhnji element XML.

Kako je to mišljeno? Ne razumem tega. Zakaj lahko vsebuje le en tak element oz. kateri element je sploh mišljen?

2.
Citat:
Preverjanje pravilnosti oznak izvedite s skladom, ki hrani trenutno veljavne oznake. Sklad implementirajte dinamično s kazalci.

Tegale tudi ne kapiram čisto. Ima mogoče kdo kakšno idejo? Vem, da je sklad gruča elementov, kjer vsak s pointerjem kaže na naslednjega, vendar na kakšen način to aplicirati v tej nalogi?


Tnx.
 

matix

Fizikalc
22. jul 2007
2.132
0
36
35
Sem še malo gruntal in prišel do glavnega koncepta: Najprej program pregleda, če so vsi tagi v parih. Nato programček potuje po fajlu od začetka in v sklad vpisuje odprte tage. Ko doseže zaprti tag, pogleda, če je na vrhu tag, ki ga zapirajoči tag zapira. Če je to res, potem se zadnji tag v skladu odstrani. Če na vrhu ni pravi odprti tag, xml file ni valid. Recimo <oseba><ime></oseba></ime> ni pravilno.

Zdaj je moj problem še implementacija v C-ju. Preklet hudič še stringov ne pozna. V glavnem ne vem, kako bi implementiral ta sklad xml tagov, kjer vsak kaže na naslednjega.. pomoč dobrodošla
smile-1.gif
 

philips

Guru
Osebje foruma
Administrator
17. avg 2007
9.860
689
113
Pa morate obvezno delati v Cju ? C++ ne pride v poštev ? Ker za parsanje stringov se mi zdi da C ni ravno primeren.
Drugače pa lahko sklad realiziraš kot dinamično povezan seznam, kjer dodajaš/odstranjuješ samo prvi element v seznamu. Jaz imam to implementirano v C++, tako da če hočeš, ti lahko pošljem (mogoče ti bo kaj koristilo).
 

philips

Guru
Osebje foruma
Administrator
17. avg 2007
9.860
689
113
Ja kaj naj rečem, uporabiš pač tabelo characterjev (dovolj veliko, da bo šlo vse not, recimo 10.000 znakov), potem pa uporabiš strlen() da vidiš kolko je dejansko teksta not.
Potem pa greš lepo s for zanko skozi in iščeš < in si zapomniš znake med < in prvim presledkom ali > - te znake tudi dodaš na sklad.
V primeru da naletiš na </, pa pogledaš ali je tag na vrhu sklada (in ga seveda odstraniš) - drugače pa vržeš error.

Zdaj ko tak gledam, niti ni tako težko za naret. Samo C uporabljat za take stvari pa je še vseeno bedarija.
 

matix

Fizikalc
22. jul 2007
2.132
0
36
35
Citat:
Uporabnik philips pravi:
Ja kaj naj rečem, uporabiš pač tabelo characterjev (dovolj veliko, da bo šlo vse not, recimo 10.000 znakov), potem pa uporabiš strlen() da vidiš kolko je dejansko teksta not.
Potem pa greš lepo s for zanko skozi in iščeš < in si zapomniš znake med < in prvim presledkom ali > - te znake tudi dodaš na sklad.
V primeru da naletiš na </, pa pogledaš ali je tag na vrhu sklada (in ga seveda odstraniš) - drugače pa vržeš error.

Zdaj ko tak gledam, niti ni tako težko za naret. Samo C uporabljat za take stvari pa je še vseeno bedarija.

Hvala! Vem, da je bedarija, zato raje ne bom omenjal še naslednje naloge (izdelava nekakšne knjižnice funkcij za analizo in manipuliranje nizov), ki jo moram ravno tako narediti v C. Kaj češ, FRI pač. Drugače sem pa našel eno skripto, ki dobro razloži sklad ( link) - upam, da mi bo ratalo.
 

doto

Fizikalc
25. jul 2007
3.175
0
36
Sklad implementiraš kot struct:

struct item{
char name[50];
item *next;
} ;

top node ima pointer naslednji na NULL, vsak naslednji pa kaže na prejšnjega;

se pravi:

struct item *top, *n;

// dodajanje
// prvi element

n = (struct item *) malloc(sizeof(struct item));
strcpy(n->name, "ime_xml_nodea");
n->next = NULL;
top = n;

// drugi element
n = (struct item *) malloc(sizeof(struct item));
strcpy(n->name, "ime_xml_nodea");
n->next = top;
top = n;

// itd ...

// branje

char name[50];
strcpy(name, top->name);
struct item *n2 = top;
top = n2->next;
free(n2);

Napišeš si funkcije za dodajanje in branje elementov void push(const char *name) in void pop(char *name). Pa paziti moraš, da sproščaš spomin, ki ga alociraš z malloc.
 

matix

Fizikalc
22. jul 2007
2.132
0
36
35
Citat:
Uporabnik doto pravi:

// prvi element

n = (struct item *) malloc(sizeof(struct item));
strcpy(n->name, "ime_xml_nodea");
n->next = NULL;
top = n;

Lahko prosim ta del kode razložiš? Recimo program bere datoteko a.xml, prepozna tag recimo <blabla> in ga shrani kot string v char array. Kam potem vtaknem ta array v ta del kode, ki sem ga citiral?

Pa hvala!!
 

doto

Fizikalc
25. jul 2007
3.175
0
36
// kreiraš novi element
n = (struct item *) malloc(sizeof(struct item));

// propertyju name prirediš neko vrednost, v tem primeru ime node-a iz xml-a
strcpy(n->name, "ime_xml_nodea");
// pointer na naslednji element je NULL, ker je to prvi element v skladu
n->next = NULL;
// pointer top nastaviš na ta element. top vedno kaže na zadnji element v skladu
top = n;

Se pravi namesto "ime_xml_nodea" daš tisti char array.
 

matix

Fizikalc
22. jul 2007
2.132
0
36
35
Torej push funkcija je za dodajanje elementov, pop pa za brisanje?

Torej:

prvi element, ki ga dodam v sklad gre takole:

n = (struct item *) malloc(sizeof(struct item));
strcpy(n->name, "ime_xml_nodea");
n->next = NULL;
top = n;

vsi naslednji pa tako:
n = (struct item *) malloc(sizeof(struct item));
strcpy(n->name, "ime_xml_nodea");
n->next = top;
top = n;

Je to prav?

Zdaj pa branje zadnjega elementa v skladu. Če se bo ujemal z zaključnim tagom, moram zadnji element zbrisati, v nasprotnem primeru pa vse skupaj prekiniti in izpisati invalid xml file. Kako si nastavim pogoj, če se zaključni element "xml_tag" ujema z najvišjim elementom v skladu, je tole spodaj prav?

char name[50];
strcpy(name, top->name);
if (strcmp( name, trenutni_zakljucni_xml_tag)==0){
struct item *n2 = top;
top = n2->next;
free(n2);
}


Najlepša hvala za pomoč, pa še 5 zvezdic leti
smile-1.gif
 

doto

Fizikalc
25. jul 2007
3.175
0
36
Jaz bi si naredil funkcije, da imaš kodo za delo s skladom ločeno.

struct item *top= NULL;

void sklad_dodaj( const char *str){
struct item *n = (struct item *) malloc(sizeof(struct item));
strcpy(n->name, str);
n->next = top;
top = n;
}

void sklad_odstrani(){
if(top == NULL) return;
struct item *n2 = top;
top = n2->next;
free(n2);
}

Pol maš pa kodo:

sklad_dodaj("tag1");
sklad_dodaj("tag2");
sklad_dodaj("tag3");
...

if( strcmp(top->name, trenutni_zakljucni_xml_tag) == 0) sklad_odstrani();