Új hozzászólás Aktív témák
-
Sk8erPeter
nagyúr
philoxenia jóarc volt, és kérésemre megváltoztatta a topic nevét egy kissé tisztességesebbre. Szerintem a "C++ gyors segitseg kellene" cím helyett a "C++ programozás" kicsit jobban hangzik.
Sk8erPeter
-
Sk8erPeter
nagyúr
válasz WonderCSabo #716 üzenetére
Dehát akkor ilyen alapon az if-ek helyett valóban lehet switch-case is, semmivel sem csúnyább, sőt.
Sk8erPeter
-
Sk8erPeter
nagyúr
Hali!
Van egy olyan feladatom, amivel kapcsolatban kíváncsi lennék a véleményetekre, hogy milyen megoldásokat javasoltok.
Egész pontosan ez a feladat szövege:
"Készítsen tetszőleges hosszúságú sorokból álló szöveges állományt reprezentáló objektumot! Valósítsa meg a UNIX tail(1) program funkcióit!
Valósítsa meg az összes értelmes műveletet operátor átdefiniálással (overload), de nem kell ragaszkodni mindenáron az operátorok átdefiniálásához!
Amennyiben lehetséges használjon iterátort!
Demonstrálja a működést külön modulként fordított tesztprogrammal!
A UNIX parancsok pontos leírását a man paranccsal kérdezheti le.
A parancs nevét követő zárójelben a man kötet sorszáma található.
A megoldáshoz NE használjon STL tárolót vagy algoritmust!"A tail() program lényege, hogy kiírja a standard outputra egy paraméterként kapott állomány utolsó 10 sorát. További paraméterezéssel az is elérhető, hogy az utsó n sort vagy n byte-ot írja ki az állományból (a 10 csak alapértelmezett), vagy akár az n-edik sortól kezdődően írja ki egy állomány tartalmát.
Kérdésem hozzátok az lenne, hogy ennek az OOP-s szemléletben történő megvalósítását hogy képzelnétek el? Maga a fájl beolvasása legyen külön osztály, aminek a tagfüggvényeit örökli egy másik, pl. a Tail osztály?
Itt találtam egy lehetséges megvalósítást (átláthatóság kedvéért felraktam a pastebinre), aminek azonban az OOP-hez nem túl sok köze van, nekem viszont objektum-orientáltan kell megvalósítanom az egészet. Ja, és STL-tároló sem használható.Így elsőre milyen javaslataitok lennének a konkrét megvalósítással kapcsolatban?
Hány osztály, milyen tagfüggvények, stb.?Ja, és miért tail(1)? Mi zárójelben az az (1)?
Előre is köszi minden javaslatot!
[ Szerkesztve ]
Sk8erPeter
-
Sk8erPeter
nagyúr
válasz Sk8erPeter #727 üzenetére
A legutsó hülye kérdés volt, ott volt a válasz, hogy "A parancs nevét követő zárójelben a man kötet sorszáma található."
Azt az operátor átdefiniálós dolgot ilyen sablonszerűen minden feladatba beleírták, tehát ahhoz szerintem az én esetemben nem igazán kell ragaszkodni, tekintve, hogy szerintem itt nincs igazán értelme mit overloadolni.
Már nagyjából tanultuk, hogyan lehet saját iterátort létrehozni, de jelen esetben nem igazán látom gyakorlati hasznát, itt nem kell randomszerűen tudni elérni elemeket, vagy gyorsan az elejére, majd a végére ugrani, vagy hasonló, mint a klasszikus iterátoroknál, így itt nem látom olyan sok értelmét. Vagy mégis van? Esetleg velük végig lehet menni a sorokon, esetleg karaktereken....
De ez sima indexeléssel is elérhető, most itt nem tudom, van-e értelme készíteni iterátort.Ha valakinek eszébe jut ötlet, akkor megköszönöm, ha leírja.
Sk8erPeter
-
Sk8erPeter
nagyúr
válasz sghc_toma #730 üzenetére
Hali!
Köszi, de a feladatkiírásban az is benne van, hogy STL-tárolót NEM szabad használni, így értelemszerűen nem tárolhatom a könyvtári vectorban, saját tárolót kell létrehozni. Épp ez nehezíti az ügyet, ha lehetne STL-t használni, akkor elég gyorsan kész lenne a feladat.
Az std::for_each ugyanígy STL-algoritmus...Az iterátorok létrehozására itt található egy elég jó módszer: [link].
Igazából az operator+ fájlösszefűzés, meg a többi felüldefiniálás jó ötlet, de pl. az összefűzésnek a tail program szempontjából nem biztos, hogy van értelme, mivel ennek nem is alapfunkciója az összefűzés.
Igen, a szöveges állomány egy objektum, de akkor ennek az osztálynak milyen tagfüggvényei legyenek? Beolvasás, utolso_x_sor(), utolso_x_byte(), stb., egyéb ötletek? Vagy akkor inkább az lenne a jobb módszer, ha ezt az egész objektumot átpasszolnám egy Tail osztálynak, amiben lennének az említett utolso_x_sor(), utolso_x_byte() függvények, amik aztán feldolgozzák az objektumot, és a kívánt sorokat/byte-okat visszaadják a mainnek?
Bocs, hogy ennyi kérdésem van, csak mielőtt nekimegyek a feladatnak, mint tót az anyjának, azelőtt jobb gondolkodni, mi lenne az ideális és egyben kényelmes módszer.Sk8erPeter
-
Sk8erPeter
nagyúr
Eddigi olvasgatások alapján a Szoftverfejlesztés C++ nyelven c. könyv elég jónak tűnik, de feltételezi a C nyelv ismeretét, nem írtad, hogy van-e ilyen alapod.
Ha nincs, akkor pl. a Programozzunk C++ nyelven c. könyv.Ezenkívül/ehelyett biztos a többiek is tudnak még ajánlani megfelelő forrásokat.
[ Szerkesztve ]
Sk8erPeter
-
Sk8erPeter
nagyúr
Legközelebb azért az ilyen hosszúakat légyszi a pastebin.com-ra, vagy a pastie.org-ra copy-paste-eld, ezeken az oldalakon szépen kiemeli a szintaktikát is (ha bejelölöd, hogy pl. C++ nyelvű forráskód), és így könnyebb áttekinteni, mint itt a PH-n. Ja, és ide csak dobd be a linket, amit kapsz a bemásolás után.
[ Szerkesztve ]
Sk8erPeter
-
Sk8erPeter
nagyúr
Hali!
Az eredeti kód azért nem fordul, mert void visszatérési értékű a getParameter() függvényed a Gift osztályban, ami miatt a cout elszáll.
Ezt megoldhatod úgy, hogy inkább double visszatérési értékűvé változtatod:
double getParameter(){ return 0; }; /// void getParameter(){} helyettDe ennél a kiíratást egyszerűbben oldanám meg, mondjuk lehetne minden osztálynak egy void print() művelete, ami épp a feladat által kiírt tulajdonságokat írná ki.
Egy lehetséges példa a Te feladatodra vonatkozóan:
-a Gift osztályban deklarálj egy
virtual void print();
függvényt, az összes többi osztályban pedig egy sima (nem virtuális)
void print();
függvényt.
-maga a megvalósítás pedig a következőképpen nézhetne ki (csak egy lehetséges megoldás, lehetne rajta bőven csiszolni, de gyorsmegoldásként szerintem megfelel):using namespace std;
void Gift::print()
{
cout << "Weight: " << baseWeight << endl;
cout << "Quantity: " << db << endl;
}
void ColoredEgg::print()
{
cout << "Name: Colored Egg" << endl;
cout << "Quantity: " << getWeight() << endl;
//Paraméter:
char colours[4][7] = { "RED", "GREEN", "BLUE", "VIOLET" };
cout <<"Color: "<< colours[colour] << endl;
}
void ChocolateFigure::print()
{
cout << "Name: Chocolate Figure" << endl;
cout << "Quantity: " << getWeight() << endl;
//Paraméter:
std::cout <<"Melting Point: "<< MeltingPoint << endl;
}
void Candy::print()
{
cout << "Name: Candy" << endl;
cout << "Quantity: " << getWeight() << endl;
//Paraméter:
char quality_names[4][5] = { "HARD" , "SOFT" };
std::cout <<"Quality: "<< quality_names[quality] << endl;
}-Ezenkívül szerintem a destruktort a Gift osztályban virtuálissá kellene tenned, hogy ne legyen memóriaszivárgás:
virtual ~Gift() {}
A Testing.cpp-ben pedig a for ciklus akkor ez alapján a következőképpen nézhetne ki (a többi rendben van):
for (int i = 0; i < 3; i++) // kiíratjuk
{
cout << "************************" <<endl; //csak az elválasztás kedvéért
Present[i]->print();
}Sk8erPeter
-
Sk8erPeter
nagyúr
válasz Mr. Teddy #763 üzenetére
Nem ártott volna, ha leírod, milyen módon hoztad most létre a tömbödet.
Hogyan növeled a méretét? Dinamikusan kezeled, nyújtózkodó tömbről van szó?Amúgy ha string osztályt használsz az #include <string> után, akkor azzal elég kényelmesen tudsz dinamikusan hozzápakolászni elemeket, pl. egy string * buffer változóba (feladattól függően simán string buffer is elég (* nélkül) ), és azon is ugyanúgy végig tudsz rohangászni indexeléssel.
Itt vannak az elérhető függvények: string class, itt meg példa pl. a hozzáfűzésre: append.[ Szerkesztve ]
Sk8erPeter
-
Sk8erPeter
nagyúr
Akár úgy is megoldhatod, ahogy itt szerepel: istream::read - C++ Reference
// read a file into memory
#include <iostream>
#include <fstream>
using namespace std;
int main () {
int length;
char * buffer;
ifstream is;
is.open ("test.txt", ios::binary );
// get length of file:
is.seekg (0, ios::end);
length = is.tellg();
is.seekg (0, ios::beg);
// allocate memory:
buffer = new char [length];
// read data as a block:
is.read (buffer,length);
is.close();
cout.write (buffer,length);
delete[] buffer;
return 0;
}Viszonylag primitív (de végül is célravezető) megoldás, a fájl végére ugrik, így tudja meg a fájl méretét, ennek megfelelő helyet foglal, majd vissza az elejére, és elkezdi a beolvasást fájl végéig.
De emvy megoldás-javaslata is tökéletes.
---------------------------------------------------------------------------------------------
Szerk.:
(#771) j0k3r!
persze, a string típus is teljesen jó.PÉLDA:
string::push_back// string::push_back
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main ()
{
string str;
ifstream file ("test.txt",ios::in);
while (!file.eof())
{
str.push_back(file.get());
}
cout << str;
return 0;
}Sokkal rövidebb is a kód.
[ Szerkesztve ]
Sk8erPeter
-
Sk8erPeter
nagyúr
Ja bocsi, az elkerülte a figyelmem, hogy az a lényeg, hogy szavanként tárold el.
Az sem túl nehéz, akkor meg csináld azt, hogy mondjuk sima string helyett string*-ot használsz.Írtam egy példát, bevallom, nem igazán néztem át, hogy helyes-e, és mivel láttam, hogy sürgős, elég gyorsan írtam, így lehetnek benne hibák, mindenesetre kipróbáltam, és működik.
Az eredeti példa analógiájára csináltam, de kissé átalakítva.Így néz ki:
// string::push_back
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main ()
{
ifstream file ("teszt.txt",ios::in);
if( !file.good() ){ //Fájlpara
cout<<"Hiba a fajllal...";
}
else //OK
{
string* words;
const int default_size=100; //kezdetben pl. 100 méretű tömböt hozunk létre
words=new string[default_size];
int size=default_size; //eltároljuk az alapértelmezett (kezdő)méretet, ha kell, növelünk
int count=0; //hol tartunk a tömbben? (egyszerűbb nyilvántartani)
while( file.good() ) //countot majd a cikluson belül növeljük
{
char c=file.get();
if(c==' ') count++; //szóközt kaptunk, növelünk, következő helyre tároljuk a szót
if(count<default_size){ //még beleférünk
words[count].push_back(c);
}
else{ //nyújtózkodunk
//pl. duplázzuk a kezdőméretet
string* tmp=new string[size*2]; //átmeneti változó, kétszeres kezdőmérettel
for(int uj=0;uj<count;uj++){ //csak count-ig van értelme menni, csak addig töltöttük fel
tmp[uj]=words[uj];
}
size*=2; //duplázzuk
tmp[count].push_back(c);
delete[] words; //töröljük az eredeti adatait
words=tmp; //végül belemásoljuk a nyújtott mérettel
}
}
for(int i=0;i<count;i++){
cout <<"i: "<<i<<".: "<< words[i] << endl;
}
}
return 0;
}Sk8erPeter
-
Sk8erPeter
nagyúr
Ezt könnyű megoldani, csináld azt, hogy az if(c==' ') count++; rész után tegyél egy nagy else blokkot, a következőképpen:
if(c==' ') count++; //szóközt kaptunk, növelünk, következő helyre tároljuk a szót
else{
if(count<default_size){ //még beleférünk
words[count].push_back(c);
}
else{ //nyújtózkodunk
//........
//........
}
}És ezzel elvileg jó.
Sk8erPeter
-
Sk8erPeter
nagyúr
Hali!
Van egy kérdésem fájlkezeléssel és a standard bemenet objektumként való kezelésével kapcsolatban. Jól jönnének az ötletek!Van egy File osztályom, amiben a számomra szükséges metódusokat valósítom meg fájlkezeléssel kapcsolatban, és az osztály konstruktorának van egy default NULL értékkel ellátott paramétere - a konstruktornak át lehet adni egy fájlnevet, amit ugyanitt a konstruktorban majd megnyitok, stb.
Ha a paraméter üres (NULL), akkor majd a standard inputról kellene olvasnom.
A konstruktor fejléce így néz ki:
File(const char * filename=NULL);A fájlkezeléshez létrehoztam egy
ifstream file_to_process;
tagváltozót (private), ez lesz az, amibe majd megnyitom a fájlt, amiből olvasok, stb., a standard inputról meg getchar-ral olvastam - ez viszont, ha már OOP, nem egy túl elegáns megoldás, ezért gondoltam arra, hogy akkor a változót istream-mé kéne tenni, ennek úgyis származtatott osztálya az ifstream, majd megoldom úgy - és akkor végül is a cin-t objektumként kezelem.
Ezért átalakítottam így:
istream file_to_process; //ifstream helyett!Na de most az a para, hogy viszont így a korábban létrehozott metódusok nem működnek, az olyanok, mint pl. a következő:
file_to_process.open(filename, ifstream::in) //vagy ios::in ???Hogyan tudnám ezt a legegyszerűbben megoldani, hogy ezek a metódusok működjenek istream-mel is?
Előre is köszi az ötleteket!
Remélem valamennyire érthetően írtam, ha nem, kérdezzetek, köszi![ Szerkesztve ]
Sk8erPeter
-
Sk8erPeter
nagyúr
válasz Jester01 #806 üzenetére
Hali!
Köszi a választ!A parám igazából éppen az, hogy ha átírom az ifstream típust istream-re, akkor a fordító már jogosan pampog, hogy miért akarok mondjuk egy close() függvényt egy ilyen tagváltozóra meghívni.
A legtöbb függvényem tulajdonképpen elsősorban fájl-specifikus, van olyan metódus, ami megnyit, van olyan, ami bezár (direkt itt nyitom meg, és nem mondjuk a main()-ből, hogy rugalmasabb legyen!), van olyan, ami megmondja a fájl méretét, fájl elejére vagy végére ugrik (a clear() metódus nélkül a fájlvégre éréskor már nem megy a seekg()-vel a fájlméret-lekérdezés, ezért tartottam érdemesnek külön függvénybe bepakolni), és így tovább.Ez a dolog egyébként a linuxos tail program megvalósításához kellene, aminek a feladat-kiírását korábban itt írtam: [link]
A standard inputról olvasás itt akkor kellene, amikor a júzer nem ad meg fájlnevet paraméterként - épp, ahogy a Linuxon is működik a tail.
Na, és a fájlkezelést, valamint egy tároló feltöltésének függvényét is bepakoltam ebbe a File osztályba, amit említettem, és gondoltam ha a paraméterben nincs megadott fájlnév, akkor lehetne cin-ről olvasni.Akkor szerinted érdemes inkább a standard inputról olvasásra külön osztályt létrehozni?
Sk8erPeter
-
Sk8erPeter
nagyúr
"A fajlmeret-beolvasas nem mukodik"
Már miért ne működne?
Legfeljebb akkor lehet gond, ha már fájl végéhez értünk (pl. egyszer már beolvastuk az állományt), de ekkor kiadsz egy clear()-t, és megint menni fog.Fájlméret-lekérdezés:
ifstream file_to_process("test.dat" , ifstream::in);
//fájl elejéhez ugrás:
if( (int)file_to_process.tellg() != 0) //ha nem az elején vagyunk
file_to_process.clear(); //ha EOF-hoz értünk, már nem menne enélkül...
//elejére ugrunk
file_to_process.seekg(0, ios::beg);
//végére ugrunk
file_to_process.seekg(0, ios::end);
//hol tart?
long length =(long) file_to_process.tellg();
//méret kiírása
cout<<"File merete: "<<length<<" byte"<<endl;[ Szerkesztve ]
Sk8erPeter
-
Sk8erPeter
nagyúr
Innen letölthetsz C++-os jegyzeteket (előadónk oldala), a lényeg röviden elég jól benne van mindegyik anyagrészből: [link] (most épp le tudod tölteni, félév elején eltűnnek a linkek (mondjuk a cím elérhető), hogy lehessen látni, épp hol tartunk)
(#811) emvy: tudom én, hogy tudod.
Sk8erPeter
-
Sk8erPeter
nagyúr
Egyébként a vector, string és ehhez hasonlók az STL-tárolók témakörbe tartozik.
Igen nehéz lenne általánosan megfogalmazni, mikor melyik típus jó, de pl. a vector egy olyan osztály, amelynek sablonparaméterként át lehet adni a típust. Elég hasznos, mert így szinte bármilyen adattípust tudsz kezelni (egész számok, karakterek, karaktertömbök, stb.).Sk8erPeter
-
Sk8erPeter
nagyúr
válasz Nyiscsák #822 üzenetére
Ilyen feladat itt megtalálható megoldva: InfoC (BME)
(Ez itt sima C.)
#include <stdio.h>
#include <string.h>
void megfordit(char t[]);
void spacetelenit(char t[]);
int main(){
char hello[]="indul a gorog aludni";
char masolat[50];
spacetelenit(hello);
strcpy(masolat, hello);
megfordit(masolat);
if (strcmp(hello, masolat)==0)
printf("Ez egy palindrom!\n");
else
printf("Nem palindrom.\n");
}
//Szóközöket ne vegyük figyelembe
void spacetelenit(char t[])
{
int honnan, hova;
hova=0;
/* végigmegyünk az összes karakteren */
/* "honnan" mindig nő, "hova" csak néha */
for (honnan=0; t[honnan]!=0; honnan++)
/* és ami nem space, másoljuk */
if (t[honnan]!=' ') { /* NEM 32, hanem ' '! */
t[hova]=t[honnan];
hova++;
}
t[hova]=0; /* a papagáj egyből: "lezáró NUL!" */
}
//String megfordítása
void megfordit(char t[])
{
int hossz;
int i;
hossz=strlen(t);
/* csak a feléig forgatunk, különben visszafordítanánk */
for (i=0; i<hossz/2; ++i) {
char temp;
temp=t[i]; /* három lépéses csere */
t[i]=t[hossz-1-i];
t[hossz-1-i]=temp;
}
/* lezáró NUL? van, mert maradt a helyén. */
}Sk8erPeter
-
Sk8erPeter
nagyúr
Itt vannak elég jó jegyzetek, megoldott ZH-példák, itt van egy példatár, ahol szintén elég jó megoldott példák vannak, itt van egy letölthető könyv, és így tovább.
Sk8erPeter
-
Sk8erPeter
nagyúr
válasz pityaa23 #862 üzenetére
Hali!
Készítettem egy lehetséges gyorsváltozatot, aminél csak arra kell figyelned, hogy a helyettesítendő karaktersorozat mindig hosszabb legyen, mint amire titkosítod, jelenleg így működik helyesen (pl. "al" helyett "A"-t akarsz beírni, erre igaz a feltétel) - így volt a legkönnyebb megvalósítani többek közt a string osztály alapfüggvényei segítségével (a replace() fv. különben felülírná a további karaktereket - ennek elkerülésével most nem foglalkoztam).
Remélem ezeket felhasználhatod a feladatod megvalósítása során.Itt megtalálod az általam írt kódot: [link]
Teszteltem, működik, kommenteztem, hogy érthetőbb legyen a megvalósítás.
----------
system("pause");
Ezt kitől tanultad? Meg kéne ütni!helyette sokkal szebb pl. a
cin.get();
és/vagy
getchar();
Ez egy karaktert vár, és nem közvetlen rendszerhívás, mint a system-mel kezdődők, és amik természetesen egyáltalán nem platformfüggetlenek (pl. sok rendszerhívás, ami Windows-on működik, nem működik Linuxon). Az ilyeneket kerüld, a system hívásokat csak akkor használd, ha tényleg nagyon muszáj - de egy kezdőnél általában ilyen probléma nem merülhet fel, mert a klasszikus kezdő feladatok 99,9%-a megoldható ezek nélkül - ha nem, akkor ott már a feladat kiírójával van baj...[ Szerkesztve ]
Sk8erPeter
-
Sk8erPeter
nagyúr
válasz pityaa23 #866 üzenetére
"system pause először cin.get() -et használtuk, de a tanár áttérített minket erre"
Akkor a tanárod egy... inkább nagyon finoman szólva...választhatott volna más tanári pályát.
Szokj le róla. Persze ahogy érzed.A programodat mivel fordítottad? Oltári nagy...furcsaságok vannak benne.
- SZOV(i)='A';
Ez meg micsoda? Kíváncsi lennék, milyen fordító az, ami ezt elfogadja...ugyanis ennek semmi értelme.- if(SZOV=='a'&&...
ez már megint mi?-strlenhez illik include-olni a string.h-t (ez nálam is kimaradt az előző kódban, mert sajnos Visual C++ elég engedékeny)
-annak a do-while ciklusnak sincs túl sok értelme a standard inputról való bekérésnél...ha sikertelen a beolvasás, azt nem így szokás ellenőrizni...arra pl. ott van a cin good(), eof(), stb. függvénye, és más módszerek is vannak, de nem így kell.
-ezenkívül a programodba semmiféle ellenőrzést nem vittél bele, hogy elkerüld az esetleges túlcímzést.
[ Szerkesztve ]
Sk8erPeter
-
Sk8erPeter
nagyúr
""Meg szeretnék tanulni c++ban programozni!"
Mi tart vissza?
Legyünk már egy kicsit önállóak! Menj be a könyvesboltba/könyvtárba és nézegess c++ könyveket."
Az ilyen lekezelő válaszoknak semmi értelme. Tanácsot kért, hogy miből érdemes tanulni, nem leb@szást. Attól még, mert valaki kezdő dologban kér tanácsot, nem kell lenézni. Az igaz, hogy kicsit többet írhatott volna az előtanulmányairól és céljairól.Sk8erPeter
-
Sk8erPeter
nagyúr
Sziasztok!
Van egy grafika házim, a lényege, hogy egérrel kell mászkálni labirintusban, nem is nagyon részletezném, igazából csak C++ szintaktikai kérdésem van:
ha így példányosítom az osztályt (globálisan elérhető lesz, mert a feladat miatt így kell most megcsinálnom):
My_Mouse_Class MyMouse();
és aztán így hívom meg egy függvényen belül:
MyMouse.Display();Akkor Visual Studio hibaüzenete:
"Error: expression must have class type"Ha viszont így példányosítom:
My_Mouse_Class MyMouse;
és ugyanúgy hívom meg:
MyMouse.Display();
akkor semmi baja.
Egyetlen különbség a hibás változathoz képest a zárójel hiánya.A My_Mouse_Class konstruktora maga semmi különlegesség, egyelőre üres, csak inicializáló lista van ott:
My_Mouse_Class(void): mouse_x(0.0), mouse_y(0.0) {
}Vajon a void kulcsszó miatt van az eredeti hiba? A fordító ilyenkor hibát érzékel, ha mégis a zárójeles módon hívjuk a konstruktort?Nem, a void tök mindegy, ott van-e. Legalábbis tippre amúgy is "odafordítódik".
Vagy miért?
Lehet, hogy rég volt C++, de hirtelen nem vágom a magyarázatot.[ Szerkesztve ]
Sk8erPeter
-
Sk8erPeter
nagyúr
válasz dani0907 #1020 üzenetére
Hehe, csak nem "Szoftver laboratórium 2." BME-n?
Az első mondat annak idején nálam is ugyanez volt, csak nekem a tail programot kellett elkészítenem.
A tetszőleges hosszúságú sorokból álló szöveges állományt reprezentáló objektum vizsgálgatásához én cirkuláris buffert készítettem, ami tulajdonképpen egy olyan tároló, amibe folyamatosan pakolgatod bele az elemeket (én a tároló egy adott "rekeszében" a sorokat tároltam \n-ig), és amikor a tároló megtelt, akkor elkezded újból elölről feltöltögetni a tárolódat, és ezen végezgeted a grep-vizsgálatot. Ez azért jó, mert tulajdonképpen tetszőleges hosszúságú sorokból álló szöveges állományt tudsz vizsgálgatni, nem állhat elő olyan helyzet, hogy már olyan brutálisan sok memóriát foglaltál, hogy egyszerűen nincs több szabad memória (mert mondjuk minden szart eltárolsz), viszont talán egész hatékonynak mondható módja a tárolásnak.
Ja, és gondolom nálatok is úgy van, hogy STL-t nem lehet használni, így saját tárolót kell írni.A grep mondjuk elég összetett, ahogy a példa írja, válassz ki néhány megvalósítandó funkciót, ami nem tűnik olyan brutálnak (vagy ahogy érzed ), amikhez a megfelelő kapcsolók tartoznak, és azokat írd meg. Kezdd el írni, és ha elakadtál, konkrétan kérdezz rá, hogy mire gondoltál, mi nem megy, hogy szeretnéd megvalósítani, és akkor tovább is tudunk segíteni remélhetőleg.
Sk8erPeter
-
Sk8erPeter
nagyúr
válasz dani0907 #1024 üzenetére
Hát amit én annak idején megcsináltam operátor-átdefiniálással, az a sorok tárolására szolgáló osztályban a következő:
string& operator[] (int n) // Indexoperátor a tároló megadott elemének elérésére (pl. itt egy adott sor)
Ez_a_te_taroloosztalyod& operator= (const Ez_a_te_taroloosztalyod&) // egyenlőség operátor a másik tároló lemásolásáraa tárolóosztályon belüli belső iterátor osztályban ezek lehetnek:
void operator++ () // pre-increment növelés
void operator++ (int n) // post-increment növelés
bool operator== (const iterator &other) const // egyenlő-e a két iterátor
bool operator!= (iterator &other) // egyenlő-e a két iterátor
string & operator* () // iterátor indirekcióTehát mint látható, igazából az iterátor osztályhoz kell pár operátor-átdefiniálással járó cucc, de amúgy tényleg nem kell annyira erőltetni.
Legalábbis nekem most épp nem jut eszembe más, de aztán amikor a feladatot megoldogatod, küldözgethetsz ide státuszjelentéseket, ha nem klappol valami, vagy eszedbe jutott újabb dolog, és akkor lehet, hogy még felmerül, hogy mégis kéne valami operátor-átdefiniálós metódus.Egykori előadónk honlapján megtalálsz egy konkrét példát az iterátor osztályról: [link]
Bár feltételezem a feladatleírásból, Te is BME-re jársz, Szebihez, vagy tévednék?
[ Szerkesztve ]
Sk8erPeter
-
Sk8erPeter
nagyúr
válasz WonderCSabo #1032 üzenetére
Lehet, hogy kiveri a szememet, és csak én nem veszem észre, de a linken hol látható az API-ról a leírás? Meg maguk az osztályok, stb.?
Sk8erPeter
-
Sk8erPeter
nagyúr
válasz dani0907 #1049 üzenetére
Nem láttam még a kódodat (amúgy elég bátor dolog felrakni pastebin-re, később ezzel vigyázz, mert "Számítógépes grafika és képfeldolgozás" tárgyból emiatt könnyen plágiumvád érhet! - még ha a Te kódod is került fel netre...), DE
ide pont leírtam, hogyan lehet detektálni a memóriaszivárgás forrását: [link]Szerk.: félreértés ne essék, pastebin-re felrakni a kódot egyébként nagyon is jó dolog, csak ha para lehet belőle mondjuk házinál vagy egyéb esetben, akkor nem biztos, h jó ötlet.
[ Szerkesztve ]
Sk8erPeter
-
Sk8erPeter
nagyúr
válasz dani0907 #1051 üzenetére
És gondolod, a levlistás emberkék nem olvassák ezt a fórumot? (Én is BME-s vagyok, simán lehetnék akár évfolyamtársad is. )
Igen, Cporta elég háklis bárminemű hibára, mert Linuxos fordító. Megpróbálhatnád esetleg Te is azzal.
Nekem most sajnos nincs időm debuggolgatni, de remélem, valaki rá tud nézni a kódodra!Még egy:
"Egyébként, benne van a #define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h>"
És a többi dolog, ami a linkelt hsz.-ben látszik?
Lehet, hogy nem ártana az sem.Amúgy mi az egész pontos hibaüzenet? Vagy csak ennyi, h memóriaszivárgás? Én már nem emlékszem, kaptunk-e valami egzaktabb hibaüzit. Mondjuk asszem nem.
[ Szerkesztve ]
Sk8erPeter
-
Sk8erPeter
nagyúr
válasz pityaa23 #1057 üzenetére
A nulláról egy csokiért nem hiszem, hogy túl sokan tolakodnának egy ilyen jellegű feladat megoldásáért.
Akkor lenne esélyed, ha 1.) kicsit motiválóbb jutalmat ajánlanál, VAGY 2.) már elkészítetted volna a feladat nagy részét, és ott kérnél segítséget, ahol elakadtál.Ráadásul talán időben kellett volna szólnod.
Igazából nem is értem, egyes személyek miből gondolják, hogy a topic látogatóinak legjobb szórakozása mások házi feladatának megírása a nulláról.
Sk8erPeter
-
-
Sk8erPeter
nagyúr
válasz Gyomman #1069 üzenetére
Azt egyáltalán megnézted, mit VÁLTOZTATOTT az operator>> függvényben? Csak mert a hsz.-edből nem úgy tűnt.
Jester01 megmutatta a hiányosságokat a Te kódodban, és kiegészítette még egy lehetséges példakóddal is.(#1068) j0k3r!: ez az F_file osztály konstruktora, aminek van egy inicializáló listája is, ami értéket ad az egyes tagváltozóknak, igazából csak azért írta bele a kódba, mert Gyomman teljesen kihagyta az F_file kódját, így másnál nyilván elég nehéz lenne kipróbálni, miért is nem fordul a kód.
Sk8erPeter
-
Sk8erPeter
nagyúr
int _tmain(int argc, _TCHAR* argv[])
Akkor ezt felejtsd el!
Ez viszont jó helyette:
int main(int argc, char *argv[])Viszont mivel úgysem használod fel az argumentumokat, ez is elég:
int main()---
system("pause");
Na, már megint... Ezt is felejtsd el. Ebben a topicban és a sima C-s topicban is már ötvenmilliószor volt szó róla, hogy ez nem jó. Itt én is leírtam. Akár cin.get() is jó helyette C++ esetén.Szerk.: ja, és tényleg tök felesleges ennyi szart beinclude-olni, amikor nem használod. Mindig csak a szükséges könyvtárakat include-old, ne növeld feleslegesen a kódod és a lefordított fájljaid méretét!
Kód bemásolásakor:
miután beillesztetted a kódodat, jelöld ki, és kattints a Programkód gombra. Így áttekinthető lesz.[ Szerkesztve ]
Sk8erPeter
-
Sk8erPeter
nagyúr
válasz kittamama #1091 üzenetére
Így nem sok esélyed van, a fórumot látogatók nem valószínű, hogy azzal szeretnék tölteni a hétvégéjük utsó napját, hogy "puszira" megcsinálnak valakinek egy feladatot a nulláról. Ha jutalmat ajánlanál érte, VAGY eljutottál volna valameddig, és konkrét kóddal, egész konkrét kérdésekkel, segítségkéréssel jöttél volna a topicba, úgy biztosan bárki szívesen segítene.
Sk8erPeter
-
Sk8erPeter
nagyúr
válasz kittamama #1094 üzenetére
"de nem tudom, hogy c-ben hogy valósítsam meg."
De Te a C++ topicba jöttél!Amúgy meg nem értem, ha eljutottál valameddig, akkor azt hogyan kell érteni? Szépen papíron levezetted magadnak, de a kódírásig már nem jutottál el?
Bár nem néztem végig, de a Gyuri16 által imént linkelt Wikipédia-cikkben vannak pszeudokódok is.
Ha azt nem tudod átültetni C++-ra, akkor valószínű, hogy a házi feladattal egyedül tényleg nem sokáig jutnál. Mással teljesen elkészíttetni meg totál semmi értelme, abból semmit nem tanulsz.Ha mutatsz kódot, amiből látszik, hogy próbálkoztál vele egy ideje, és van elképzelésed, de elakadtál, valaki a topicban biztosan fog tudni segíteni az előrelépésben, ha viszont egyáltalán nem megy a kódolás része, akkor valószínűsíthető, hogy nem fog megoldódni ez az ügy, legalábbis nem ebben a topicban vagy nem ingyér'.
===
(#1093) Gyuri16: igen, lehet, hogy le kéne írni az első hozzászólásban, hogy "puszira nincs komplett feladatgyártás, a topic nem erről szól ".
[ Szerkesztve ]
Sk8erPeter
Új hozzászólás Aktív témák
● ha kódot szúrsz be, használd a PROGRAMKÓD formázási funkciót!