[zap. test] 16.1. (12:30)

keff
Matfyz(ák|ačka) level I
Příspěvky: 28
Registrován: 24. 1. 2006 19:17

[zap. test] 16.1. (12:30)

Příspěvek od keff »

Zápočtová písemka z OOP, 16.1.2007 od 12:30

Zadání:
Vaším úkolem je vytvořit program, který hezky upraví kaskádový styl uložený v souboru; tzv. "pretty-printer". Náhled:

Kód: Vybrat vše

p.a1 ul.sd, #sd .fg {
	color: rgb( 128, 128, 64);
	font-family: "Arial";
	font-size: x-small;
	text-align: center
}
Konkrétně:
Jednotlivé tagy stylů jsou seřazeny dle abecedy.
Je-li ke stylu přiřazeno více tagů, jsou také seřazeny dle abecedy a odděleny čárkou a mezerou.
Je-li v názvu znak #, : nebo ., považuje se při porovnávání za oddělovač složek. Tedy p.z bude nutně před pa.a.
Prametry stylu se vypisují každý na jeden řádek, seřezené dle abecedy. Za názvem parametru je ihned dvojtečka a mezera. Jsou-li hodnoty parametru odděleny čárkou, navazuje čárka ihned za parametrem, následuje mezera. Parametr je zakončený středníkem, pouze u posledního se střeník vynechává.
Je-li hodnota složitější výraz se závorkou (např. url nebo rgb), výledek začíná jménem hodnoty, následovaný otevírací závorkou, pak hodnoty začínající mezerou a odděleny čárkou a zakončený uzavírací závorkou.
Program se volá z příkazového řádku. Prvním parametrem je jméno vstupního, nenaformátovaného souboru, druhým je jméno výstupního, formátovaného souboru. Předpokládejte, že je vstupní soubor syntakticky v pořádku.

Přišlo 5 lidí, 3 dali do konce, další 2 (including myself) ještě ladili tak nás nechal to poslat na mail. Snažil jsem se to řešit hezky objektově přes streamy které jsem aktivně požil až den předtím tak mi to trvalo :)

řešení: http://pastebin.com/860734
neoangin
Matfyz(ák|ačka) level I
Příspěvky: 26
Registrován: 4. 6. 2006 10:51
Typ studia: Informatika Bc.
Bydliště: Blava/Praha
Kontaktovat uživatele:

Je to krasny - musel jsem to sem dat

Příspěvek od neoangin »

/* ========================================= cssnice.h ================================================================ */

#include <string>
#include <vector>
#include <map>
#include <iostream>
#include <ostream>
#include <iomanip>
#include <fstream>

#include "csssoubor.h"

using namespace std;

int main( int argc, char **argv) {

if (argc != 2){
cout << "Error - usage : cssnice.exe file.css" << endl;
return 1;
}

CssSoubor parser;

ifstream infile;
infile.open( argv[1], ios::in);
if ( ! infile ) {
cerr << "Error: Can't open the input file
";
return(1);
}

infile>>parser;
cout<<parser;

infile.close();


return 0;
}


/* ========================================= csssoubor.h ================================================================ */
#include <vector>
#include <string>
#include <map>

#include "cssblok.h"

using namespace std;

class CssSoubor {
public:
friend std::ostream &operator<<(std::ostream &o, const CssSoubor &soubor);
friend std::istream &operator>>(std::istream &i, CssSoubor &soubor);
void serad();

private:
typedef vector< CssBlok> SeznamBloku;
SeznamBloku bloky_;
};


bool ftor_blok_sort( const CssBlok &a, const CssBlok &b ) {
return ( (*(a.tagy_.begin()))<(*(b.tagy_.begin())) );
}


void CssSoubor::serad() {
CssSoubor::SeznamBloku::iterator ib = bloky_.begin();
CssSoubor::SeznamBloku::iterator ie = bloky_.end();

sort(ib, ie, ftor_blok_sort);
}


std::istream &operator>>(std::istream &i, CssSoubor &soubor) {
//cte stream znaku a sype ho do bloku, ty pak pridava
while (i) {
CssBlok blok;
i>>blok;
if (!blok.empty()) {
blok.serad();
soubor.bloky_.insert( soubor.bloky_.end(), blok );
}

}
soubor.serad();

return i;
}

std::ostream &operator<<(std::ostream &o, const CssSoubor &soubor) {
//vypise hezky zformatovany css soubor
CssSoubor::SeznamBloku::const_iterator ib = soubor.bloky_.begin();
CssSoubor::SeznamBloku::const_iterator ie = soubor.bloky_.end();

while( ib!=ie ) {
o << *ib;
++ib;
}
o << endl;
return o;
}

/* ========================================= cssblok.h ================================================================ */

#include <vector>
#include <string>
#include <map>
#include <algorithm>
#include <ctype.h>


using namespace std;

class CssBlok {
public:

void serad(); //seradi tagy a pravidla podle abecedy
bool empty();

friend std::ostream &operator<<(std::ostream &o, const CssBlok &blok);
friend std::istream &operator>>(std::istream &i, CssBlok &blok);
//friend bool ftor_blok_sort( CssBlok &a, CssBlok &b );
friend bool ftor_blok_sort( const CssBlok &a, const CssBlok &b );
private:
typedef vector<string> Tagy;
typedef pair< string, string> DvaStringy;
typedef multimap< string, string> Pravidla;
Tagy tagy_;
Pravidla pravidla_;

void cti_pravidlo( std::istream &i, bool &b);
void cti_tag( std::istream &i, bool &b);

friend class CssSoubor;
};

std::istream &operator>>(std::istream &i, CssBlok &blok) {
//cte stream znaku a parsuje
bool dale;
blok.cti_tag(i, dale);

while ( dale==true ) {
blok.cti_tag(i, dale);
}

//cteme vlastnosti
blok.cti_pravidlo(i, dale);

while ( dale==true ) {
blok.cti_pravidlo(i, dale);
}

return i;

}

void CssBlok::cti_tag( std::istream &i, bool &b) {
b = true;
char c;
string tag="";

if (!i) { b = false; return; }

// sezereme whitespace
i>>c;
while ( (i) && isspace(c)) i>>c;

if (!i) { b = false; return; }

if (c=='{') {
b = false;
return;
}

while ((c!=',') && (c!='{')) {
if (!( isspace(c) && isspace(tag[tag.length()]) )) {
tag+=c;
}
i>>c;
}

//cout<<" *tag: "<<tag<<endl;
tagy_.insert(tagy_.end(), tag);

if (c=='{') {
b = false;
return;
}

}

void CssBlok::cti_pravidlo( std::istream &i, bool &b) {
//rozsekat pravidlo na _property_:_value_;
b = true;
char c;
string prop="", val="";

if (!i) {
b = false;
return;
}

//preskoc whitespace
i>>c;
while ( (i) && isspace(c)) i>>c;

if (c=='}') { //konec, vrat pair(i, false)
b = false;
return;
}

//cti property
while ( c!=':' ) {
if (!( isspace(c) && isspace(prop[prop.length()]) )) {
prop+=c;
}
i>>c;
}

//cti value
i>>c;
while ( isspace(c)) i>>c;

//cekej na ;
while (( c!=';' ) && ( c!='}' )) {
if (!( isspace(c) && isspace(val[val.length()]) )) {
val+=c;
}
i>>c;
}
if (c=='}') { b=false; }

//cout<<" *ctu: "<<prop<<" : "<<val<<endl;

pravidla_.insert( DvaStringy( prop, val ) );

//return VystupniPar( i, true );
return;
}


std::ostream &operator<<(std::ostream &o, const CssBlok &blok) {
//vypise hezky zformatovany css blok
CssBlok::Pravidla::const_iterator pie=blok.pravidla_.end();
CssBlok::Pravidla::const_iterator pit=blok.pravidla_.begin();

CssBlok::Tagy::const_iterator tie=blok.tagy_.end();
CssBlok::Tagy::const_iterator tit=blok.tagy_.begin();

while( tie!=tit ) {
o << *tit;
++tit;
if ( tie!=tit ) { o << ", "; } //dame jeste carku, prijde dalsi
}

o << " {" << endl;

while( pie!=pit ) {
o << "\t" << pit->first << ": " << pit->second << ";" << endl;
++pit;
}
o << "}" << endl;

o<<endl;

return o;
}


bool ftor_tag_sort( const string &a, const string &b ) {
int i=0;
bool delim_a, delim_b, jedeme=true;

while (true) {
delim_a=false, delim_b=false;
if ( (a=='.') || (a==':') || (a=='#') ) { delim_a=true; }
if ( (b=='.') || (b==':') || (b=='#') ) { delim_b=true; }
if (delim_a && (delim_b == false)) { return true; } //a ma oddelovac, b nema -> a je kratsi a do delim. stejne s b
if (delim_b && (delim_a == false)) { return false; } //b ma oddelovac, a nema
if ((delim_a == false) && (delim_b == false) && (a!=b)) { return (a<b); }
if ( (i<a.length()) && (i<b.length()) ) { i++; } else { jedeme = false; }
}
return false;
}
/*
bool ftor_pravidlo_sort( const DvaStringy &a, const DvaStringy &b ) {
return (a.first()<a.second());
}
*/

void CssBlok::serad() {
CssBlok::Tagy::iterator tie=this->tagy_.end();
CssBlok::Tagy::iterator tib=this->tagy_.begin();

CssBlok::Pravidla::iterator pie=this->pravidla_.end();
CssBlok::Pravidla::iterator pib=this->pravidla_.begin();

stable_sort(tib, tie, ftor_tag_sort ); // pouziti nestabilniho sortu by mohlo menit vyznam - viz color:white; color: black;
//stable_sort(pib, pie, ftor_pravidlo_sort );
}

bool CssBlok::empty() {
if (tagy_.empty() && pravidla_.empty()) {
return true;
}
return false;
}
$ man woman
No manual entry for woman
neoangin
Matfyz(ák|ačka) level I
Příspěvky: 26
Registrován: 4. 6. 2006 10:51
Typ studia: Informatika Bc.
Bydliště: Blava/Praha
Kontaktovat uživatele:

Otazka: ako si otestovat tento zdrojak?

Příspěvek od neoangin »

Chcem sa len spytat, ci by som si mohol horeuvedeny zdrojak aj vyskusat. Vsetko je zda sa .h subor, takze co ma byt v .cpp?
$ man woman
No manual entry for woman
MIKI
Matfyz(ák|ačka) level III
Příspěvky: 186
Registrován: 10. 12. 2004 22:35
Typ studia: Informatika Bc.
Kontaktovat uživatele:

Re: Otazka: ako si otestovat tento zdrojak?

Příspěvek od MIKI »

neoangin píše: Vsetko je zda sa .h subor, takze co ma byt v .cpp?
No napoviem ti: Hadr by nemal obsahovat main(). :wink:
MOTTO-1: Nieje dôležité vedieť ale pochopiť!!!
MOTTO-2: Neuč sa!!! Život ťa naučí. Mňa naučil, že sa mám učiť.
Odpovědět

Zpět na „2006“