Hirdetés

Keresés

Új hozzászólás Aktív témák

  • h1ght3chzor

    őstag

    válasz Dave-11 #1569 üzenetére

    Pointer.
    De ha mondjuk ezt írod, hogy int* t, általában egy tömbre gondolunk int t[] helyett így írjuk. :)

  • Chipi333

    csendes tag

    válasz Jhonny06 #1563 üzenetére

    És csak 1 értéket tudsz visszaadni.
    Nézőpont kérdése. Az az 1 érték lehet pointer is, ami mögött lehet tőmb vagy valamilyen egyéb adatstruktúra is :)

  • Chipi333

    csendes tag

    válasz ArchElf #1546 üzenetére

    Ha kevesebb a delete mint a new, akkor ott memory leak van :)
    this->temp = new Project [pm+1];

    Ez nem egy Projekt* tömböt csinál, hanem egy Project tömböt. És a this->temp[i]=tomb[i]; az másol nem pointert állítgat. Probléma akkor van, ha a Projecten belül is vannak pointerek, mert akkor defaultbol csak a pointer lesz másolva, és ugyanoda fog mutatni mint az eredeti. A deletekből amiatt lehetett baj, ha a Projeknek van destruktora, ami ezeket a területeket szépen felszabadítja, és az új példány meg megpróbálja ezeket elérni (vagy éppen deletnél megpróbálja újra felszabadítani). Szóval ha ez van, akkor valóban kell a copy operátor.

  • Gyuri16

    senior tag

    válasz Jhonny06 #1428 üzenetére

    a <map> egy binaris kereso fa a jobbik fajtabol, konkretan red black tree. (kulcs -> ertek) parosokat tud tarolni, es gyorsan ezekben keresni, hozzaadni.

    ilyen hierarchiat megcsinalhatsz igy:
    alkalmazott osztaly:
    - pointer a fonokre (szinten alkalmazott osztaly)
    - tomb (vagy vector, vagy map..) pointerekbol az alkalmazottakra

    ezzel az a gond, hogy nem igazan lehet benne ertelmesen keresni. tehat ha pl van mindegyiknek neve, es meg akarod keresni, hogy az adott nevu alkalmazottnak ki a fonoke, akkor egy ilyen fanal az egeszet at kellene nezned.

    ebben esetben en hozzaadnek egy map-ot amiben a kulcs a nev lenne az ertek pedig az alkalmazott. igy vegulis ket fastrukturad lenne, az egyik mutatna az egymas kozti viszonyokat (ki kinek a fonoke..) a masikkal pedig gyorsan meg tudnad talalni a megfelelo alkalmazottat az elobbi faban.

  • Chipi333

    csendes tag

    válasz Jhonny06 #1408 üzenetére

    Sima return-el csak void fv-ben tudsz visszatérni, egyébként a compilernek sikitania kéne. Ott viszont nem tudsz vele hibát jelezni, mivel ez az egyetlen visszatérési értéked, szóval nem értem a dolgot.
    Az jutott még eszembe, hogy pointer tipusnál talán null-t adna vissza de a g++ akkor is errort dobott rá.

  • proci985

    MODERÁTOR

    válasz Jhonny06 #1311 üzenetére

    izé, ezzel nem az a baj, hogy a második sor jobb oldala char típusú, a jobb oldalar meg char**?

    egy char** meg persze hogy nem lehet egyelővé tenni egy charral. na és valszeg ezért panaszkodik a típuskonverzióra a compiler. a visual studio szokott adni errort is, abból is ezt elvileg ki lehetne bogarászni.

    a const nem zavarhat be, az csak annyit jelenthet, hogy az y értéken keresztül az x nem megváltoztatható szvsz, legalábbis funkciólnál ez így van. egyébként meg ilyen kód szerintem valós esetben classon belül nem igazán fordulhat elő. ha ez nem így van, akkor is max azt jelenti, hogy a pointer értéke nem változtatható, de az se csinálhat compiler típus errort.

    vagy a harmadik ötlet: ez így design szempointból szerintem minimum fura, minek constanssá tenni egy pointert, amikor class scopeon belül azért ennyire a dolgokat szerintem nem kell védeni (illetve ha kell az már bőven régen rossz, meg amúgy sem ér semmit mert úgyis kiszedhető ez a kódrész is, ha más hozzáfér), ha meg class scopeon kívülre akarja az ember használni, akkor úgyis kell egy funkció, akinél pedig egyszerűbb írni egy constantot a funkcióra. szóval értelme ennek így semmi.

  • Jester01

    veterán

    válasz Jhonny06 #1317 üzenetére

    Igen, ez már közelít az igazsághoz. A fenti kód önmagában még nem lenne baj, vagyis az, hogy az x tudja írni az y viszont nem, az még nem probléma, millió olyan eset van amikor különböző pointereken keresztül különböző elérésed van, például:

    char c;
    char* x = &c;
    const char* y = &c;

    Ezzel semmi baj, x-en keresztül lehet írni, y-on nem.

    A gond ott kezdődik, hogy az említett struktúra módot adna olyan konverzióra aminek során a const elveszik egy pointerből. Látszólag ugye itt éppen hozzáadódik és ez biztonságosnak tűnik, de valójában egy kiskaput nyit:

    char* x;
    const char** y = &x;
    const char* z;
    *y = z;
    *x = 0;

    Itt a z pointerről leszedtük a const-ot és az x-en keresztül olyan címre írtunk amire nincs felhatalmazásunk. Ugye *y típusa const char* és z is ez, tehát a *y = z rendben van. Viszont mivel y=&x ezért most már x is ugyanoda mutat ahová z, csak x nem const vagyis *x írható.

    Mégegyszer hangsúlyoznám, nem az a baj, hogy több pointer ugyanazt a címet különböző módon éri el, hanem az, hogy egy tetszőleges const pointerből írhatót lehetne varázsolni. (Persze egy cast-tal ezt még mindig meg lehet tenni de az már más kérdés.)

  • Jester01

    veterán

    válasz Jhonny06 #1314 üzenetére

    Ja és a (bal oldalon lévő) const nem azt jelenti, hogy az érték nem változhat, hanem azt, hogy az adott pointeren keresztül nem lehet változtatni. Tehát ez is teljesen szabályos:

    char c = 0;
    const char* p = &c;
    c = 1;

  • Jester01

    veterán

    válasz Jhonny06 #1311 üzenetére

    Itt ugye nem a pointer a konstans, hanem amire a legvégén mutat (dupla indirekció után), vagyis **y nem írható.

    Ez például konstans mutató és teljesen szabályos, az y maga a konstans, vagyis y nem írható:
    char** const y = &x;

    Ez is szabályos, itt az a konstans amire az y mutat, vagyis *y nem írható:
    char* const *y = &x;

  • proci985

    MODERÁTOR

    válasz proci985 #1291 üzenetére

    csak elszúrtam.

    cout << hallgato->getAzonosito() << endl;

    kell, mert itt már egy adott objektum pointerével lesz meghívva a függvény, és nem magával a listával.

    egyébként emlékeim szerint volt erre valami egyszerűbb megoldás is.

    WonderCSabo: a pointer a gyorsabb, emlékeim szerint Lakos a Large-Scale C++ SW Designben konkrétan adott adatokat is, hogy mennyivel (nem találom az oldalt). lehet olyan eset, hogy jobban megéri teljes objektumokat átadni, de szerintem ez nem olyan.

  • WonderCSabo

    félisten

    válasz doc #1300 üzenetére

    Ez igaz, viszont a dinamikus memóriakezelés miatt fragmentálódik a memória, az elemek elérése több erőforrásba kerül, sokkal több hibalehetőség van, stb. Fv. paraméterként meg érdemes referencia szerint átadni, és nem kell másolgatni semmit. Én nem mondanám, hogy minden esetben érdemes pointereket használni.

    raadasul gyanitom, hogy olyankor az osztalyt megsemmisiti, es ugy peldanyt hoz letre a default copy construktorral, de ez csak tipp

    Sztem meg inkább std::copy-val, vagy vmi ilyesmivel másolja át az adatokat.

  • doc

    nagyúr

    válasz WonderCSabo #1296 üzenetére

    azert, mert a 4 byte-os pointerek helyett sok-sok byte meretu objektumokat kell ide-oda pakolaszni
    pl. ha fv parameterkent vagy visszateresi ertekkent hasznalod a listat, akkor akar hatalmas mennyisegu adatot kell a verembe rakni/kivenni, ami eleve nagyon lassu muvelet
    raadasul mikor a container (jelen esetben a vector) nekiall dolgozni az adatokon (pl. ha a meretnoveles miatt kenytelen az osszes elemet mashova rakni), akkor nem mindegy hogy siman atmasol egy negybyte-os pointert, vagy egy komplett osztalyt rakosgat (raadasul gyanitom, hogy olyankor az osztalyt megsemmisiti, es ugy peldanyt hoz letre a default copy construktorral, de ez csak tipp)

  • WonderCSabo

    félisten

    válasz Jhonny06 #1298 üzenetére

    Mivel te pointereket pakoltál bele a vektorba (ami sztem egyáltalán nem kell, de mindegy), így tudod elérni a vektor tagjait, pl.:

    peldany.lista[0]->GetKepzestipus();

    Szerk.: Ezek szerint jobb, ha utánanézel a dinamikus memóriakezelésnek is.

  • Jhonny06

    veterán

    válasz proci985 #1291 üzenetére

    és doc: Sajnos még mindig nem jó, bár magamtól ilyen pointeres megoldást nem tudok írni. Így sem igazán tudom értelmezni, hogy mit jelent, mi miért van, stb. :B (Mármint ez utóbbi kódban.) Én egyébként azt hittem, hogy lehet simán tömbként kezelni.

  • doc

    nagyúr

    válasz Jhonny06 #1285 üzenetére

    na azert ugy latom vannak itt eleg alapveto hianyossagok

    szoval

    az adatszerkezet (akar tomb, akar vector, akar valami mas) puszta adatszerkezet, ha ugy tetszik, egy darab a memoriaban, ami pont akkora meretu, amiben elfer az altalad megjelolt szamu es tipusu adat (osztaly, valtozo, stb)

    ha te deklaralsz egy tombot pl. int tomb[10] akkor a memoriaban egy akkora darabot, amiben 10 int tipusu ertek elfer, lefoglal a program. de arrol, hogy ott azon a memoriateruleten mi van, semmit nem tudsz (illetve annyit, hogy 'hasznalhatatlan szemet'). neked kell azzal az adattal feltoltened, amit utana ki akarsz majd olvasni belole

    ebbol adodoan a vector<Adatbazis> lista valtozod annyit mond, hogy ez egy olyan vector, amiben Adatbazis tipusu objektumok vannak, semmi tobbet. nyilvan neked kell belepakolnod az abban tarolni kivant objektumokat, maga az adatszerkezet nem fogja helyetted kitalalni hogy mit akarsz belerakni...

    raadasul teljes objektumpeldanyt (nalad Adatbazis) nem tarolunk sem tombben, sem mas adatszerkezetben, helyette az arra mutato pointert szokas (tehat vector<Adatbazis*> lista)

    a feltoltesnel meg nyilvan neked kell minden elemet hozzaadnod, a pointer eseteben a new-val letrehozva

    a vector eseteben a resize() csak annyit mond, hogy szerinted mi a maximalis darabszam, amit bele fogsz rakni, ennek megfeleloen optimalizal, ettol fuggetlenul akar kevesebb, akar tobb elem is lehet benne

    tehat ha te akarsz egy vectort amiben 10 darab Adatbazis objektum van, akkor csinalsz egy ilyet:

    for (int i=0; i<10; ++i)
    lista [i]= new Adatbazis();

    es amikor mar nem kellenek, pl. a destruktorban meg is szunteted az ojjektumokat (ez nem C#, nincs garbage collector!)

    for (int i=0; i<10; ++i)
    delete lista[i];

    ez utobbi persze szebb egy olyan megoldassal, amiben nem tarolod elore az elemek darabszamat, hanem vegigmegy a teljes listan annak meretetol fuggetlenul es kitorli mindegyik elemet

    kerdezni meg mindenki szokott az elejen, sot a kozepen is :DDD ezen ne aggodj, ha normalis hangnemben kerdezel (mint ahogy eddig is tetted) szivesen segitunk ;)

    MOD: ha a listat visszaado metodust csinalsz, figyelj arra hogy ne magat a listat, hanem arra mutato referenciat adj vissza, hogy ne kelljen feleslegesen egy csomo adatot a verembe pakolni/kivenni

    tehat nem vector<Adatbazis*> addide() {return lista;} hanem const vector<Adatbazis*>& addide() const {return lista;}

    a const ne zavarjon meg, nem feltetlenul muszaj, de erdemes raszokni a hasznalatara

  • doc

    nagyúr

    válasz Jhonny06 #1283 üzenetére

    a tomb merete az, amit veletlenszerunek szeretnel? tehat csak a konstruktorban dol el, hogy hany eleme lesz a tombnek? mert akkor ne tombot hasznalj, hanem az STL-es adatstrukturakat, pl. vectort, annak a merete dinamikusan valtoztathato
    a sima C-s tomb meretet meg kell adnod, nincs mese. illetve ugy meg megoldhato, hogy a konstruktorban lefoglalod a tomb meretenek megfelelo tarteruletet mondjuk igy:
    tomb = malloc(sizeof(Osztalynev*) * meret)
    amit aztan a destruktorbol free-vel felszabaditasz
    de ilyet ugyebar nem csinalunk, C++ -ban C++-szul beszelunk, tehat vector, esetleg list :)

    MOD: akkor ugy tunik, megintcsak nem ertettelek :D

    tehat te Osztalynev tomb[10] modon deklaraltad?
    mert akkor a new Osztalynev() tenyleg nem fog belemenni, tekintve hogy az egy pointer, de meg a teljes osztalyt tartalmazo tombot csinaltal (ez utobbit NE!)

  • Jester01

    veterán

    válasz modder #1147 üzenetére

    pointer tömböt inicializálsz, mert egy pointer egy int méretű

    A pointer nem feltétlenül int méretű de ennek jelen esetben nincs is jelentősége.

  • modder

    aktív tag

    válasz Blaise7 #1146 üzenetére

    Helló, természetesen igen, de nem pontosan abban a formában, ahogy leírtad.

    Heterogén kollekciónak hívják, és a lényeg, hogy bármilyen osztály objektumait beleteheted, amik a kollekció típusának leszármazottai.

    Legyen

    class Os {};
    class Gyerek: public Os {};

    Os* tomb[10];

    Ahogy látod Os* (azaz Os-re mutato pointer) típusokat tárolok a tombben, és ha hozzá akarok adni egy elemet, akkor a címét kell hozzáadni:
    Os[0] = new Gyerek;
    vagy

    Gyerek gyerek;
    Os[1] = &gyerek;

    Ez az egyetlen módja, hogy egy tömbben gyerek osztályokat is tudj tárolni. Az oka az, hogy a két osztály memóriatérképe eltérő. Amíg Os-ben lehet pl. 1db int, addig Gyerekben legyen 10db float, plusz az Os 1db intje.
    Ha Os tipusu tombot inicializálsz, akkor a memóriában (a te esetedben) 10db Os osztály méretű hely foglalódna a memóriában, ami a fentiekből adódóan 10 * 1db int-et jelentene.
    Erre a helyre nyilván nem férne bele a 10 * (10db float + 1db int), ami a gyerek osztály mérete.

    Az egyetlen módszer, hogy pointer tömböt inicializálsz, mert egy pointer egy int méretű, és bármilyen memóriacímre mutathat.

    Remélem érthető voltam, keress rá a C++ heterogén kollekcióra.

  • j0k3r!

    őstag

    válasz FireKeeper #1040 üzenetére

    hello!

    fopen
    mivel az elso parameter egy char *, igy szerintem nem lesz vele sok gondod. (de azert erdemes lekezelni a 'hibas' filenevet, valamint a FILE pointert ellenorizni hasznalat elott, valamint nem elfelejteni az fclose-t hasznalat utan)

  • j0k3r!

    őstag

    válasz DiscoStu #1036 üzenetére

    char *id vs. char id[5]

    char *id egy pointer, ami a kezdocime egy karakterlancnak (karaktertombnek), aminek nem tudjuk a hosszat (futasidoben dol el), ezt hasznaljuk dinamikus memoriafoglalasnal.

    amit te 2 lepesben tettel meg:
    char *id; // definialtal egy pointert
    id=new char[5]; // megadtad a meretet

    azt o megtette 1 lepesben (kihasznalva, hogy tudjuk elore, hogy max 4 karakter lehet):
    char id[5]; // 5 elemu karaktertombot hoz letre

    fontos! mindig n + 1 db char-t kell foglalni, mivel van a vegen egy lezaro \0 (amibol kovetkezik, hogy egy karakterlanc elejet a pointer, veget a lezaro \0 hatarozza meg).
    egy kis olvasnivalo evvel kapcsolatban: [link]

    esetleg mitől függ hogy melyik verziót érdemes használni?

    attol, hogy tudod-e elore, hogy maximum (vagy pontosan) mekkora teruletet kell foglalnod.

  • Gyuri16

    senior tag

    válasz Gyuri16 #1027 üzenetére

    ok, ez igy hulyeseg :)

    kozben rajottem, mi volt a lenyegi gond, tehat az operator[] fv-nek egy referenciat kell visszaadni, itt konkretan egy pointerre.
    erre jutottam, leirom azoknak, akik az elozot elolvastak es nem ertik min kinlodok :)
    (ha esetleg lehet jobban, szoljatok)

    #include <iostream>
    #include <vector>

    using namespace std;

    class ChildList {
    private:
    vector<int *>* v;
    public:
    ChildList(int n) {v = new vector<int *>(n);}
    int* & operator[] (const int index);
    };

    int * & ChildList::operator[](const int index) {
    return (*v)[index];
    }

    int main(int argc, char **argv) {
    ChildList cl(10);
    int * a = new int(5);

    cl[0] = new int(5);
    cl[1] = a;
    cout << *cl[0] << *cl[1];

    return 0;
    }

  • Gyuri16

    senior tag

    segitseget kernek pointerek vs operator overloading temaban. egy fa adatstrukturat csinalok, ahol minden node-nak lehet valamennyi pointere a gyerekeire. ezt egy vector<Node*> segitsegevel kepzeltem. elore kell lefoglalni a kontruktorban megadott szamu pointernek a tombot (akkor is ha null lesz csak az erteke) es fokozatosan hozzaadni a gyerekeket (tudom, hogy lehet jobban is, azt kesobb csinalom. a feladat osszehasonlitani a kulonbozo megoldasokat). szeretnek a Node osztalynak egy [] operatort, amivel a gyerekekhez pointerekkent lehetne hozzaferni. egyelore mindig referenciakkal csinaltam hasonlot,megmutatom mire jutottam:

    class Node {
    public:
    int sigma;
    // Node** child;
    vector<Node*>* child;
    int value;
    Node(int sigma);
    ~Node();
    Node& operator[](const int index);
    };

    Node& Node::operator[](const int index) {
    return *(*child)[index];
    }

    Node::Node(int sigma): sigma(sigma), value(0) {
    /* child = new Node *[sigma];
    for (int i = 0; i < sigma; i++) {
    child[i] = NULL;
    }*/

    child = new vector<Node*>(sigma);
    }

    Node::~Node() {
    /* for (int i=0; i < sigma; i++) {
    if (child[i] != NULL) {
    delete child[i];
    }
    }
    delete [] child;
    */

    for (vector<Node*>::iterator it = child->begin(); it < child->end(); ++it) {
    delete *it;
    }
    delete child;
    }

    ami a kommentarokban van, az a regi megoldas tombokkel ami mukodik is jol, olyat szeretnek csak vectorral es operatorral, tehat ami eddig n->child[i ] volt az legyen n[i ] .

    ezt az osztalyt kesobb szeretnem igy hasznalni:

    Node n = new Node(10);
    Node n[0] = new Node(10);
    stb..

    remelem ertheto mi a problema, koszonom elore a segitseget.

  • doc

    nagyúr

    válasz #94180096 #983 üzenetére

    ha tenyleg ket ( ) van a fv neve utan, es nem fv pointert ad vissza (mijaza rekord? :F ) akkor ez nagyon nem jo... mit szeretnel? ja es mijaza rekord? :DDD

  • sghc_toma

    senior tag

    válasz papa019 #837 üzenetére

    a Termekek.h-ban van egy ilyen:

    Product& operator<(Product& j1,Product& j2);
    ez ugye nem OK, bool a helyes visszateresi ertek..

    meg egy ilyen:

    return strcmp(j1.get_name(),j2.get_name());

    ez nem jo, mert akkor igaz, ha nem egyenlo a ket nev, nem akkor, amikor az elso kisebb..

    Es ami a fo problema: a vektorban ugye pointereket tarolsz, az operator< meg referenciakkal dolgozik, ez igy nem okes.. tehat kell egy osszehasonlito fv., ami valahogy igy nez ki:

    bool compare(Product * p1, Product * p2)
    {
    return strcmp(p1->get_name(), p2->get_name()) < 0;
    }

    ezt megadhatod harmadik parameternek a sort-nak..
    remelem nem neztem el semmit (kicsit sietve futottam at a kodot, eppen beadandot irok :) )

  • Jester01

    veterán

    válasz Tuostein #760 üzenetére

    Azt kell eléírni :K
    Ha tömbben lévő értékeket akarod módosítani, akkor nem kell. Itt viszont magát a tömböt (a kezdetére mutató pointert) akarod módosítani, tehát kell a referencia.

  • papa019

    senior tag

    válasz Jester01 #748 üzenetére

    Köszi, rengeteget segítettél, kijavítottam az általad említett hibákat.
    A Vector.h-ban a 2. paraméter elé odaírtam a const-ot, illetve beírtam az os<<' '<<v.at(i).print(os); sort is.

    Nekem viszont nem fordul és ezt írja ki:

    "d:\egyetem\2. félév\programozás alapjai 2\khf\7.hazi\7\7\vector.cpp(127) : error C2662: 'HomeMadeString::String::print' : cannot convert 'this' pointer from 'const HomeMadeString::String' to 'HomeMadeString::String &'"

  • papa019

    senior tag

    Sziasztok.
    Van egy hatalmas problémám. :S

    Stringekből (osztály) álló vektor osztályt kellett készítenünk.
    Minden megy szuperül egy dolgot kivéve:

    //using namespace std;
    ostream & operator << (ostream& os, const Vector &v)
    {
    for(unsigned int i=0;i<v.elementNum;i++)
    {
    os<<' '<<v.at(i);
    }
    return os;
    }

    Így olyan hibákat dob ki a rendszer, hogy:

    1>d:\egyetem\2. félév\programozás alapjai 2\khf\7.hazi\7\7\vector.cpp(124) : error C2143: syntax error : missing ';' before '&'
    1>d:\egyetem\2. félév\programozás alapjai 2\khf\7.hazi\7\7\vector.cpp(124) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    1>d:\egyetem\2. félév\programozás alapjai 2\khf\7.hazi\7\7\vector.cpp(124) : error C2065: 'os' : undeclared identifier
    1>d:\egyetem\2. félév\programozás alapjai 2\khf\7.hazi\7\7\vector.cpp(124) : error C2059: syntax error : 'const'
    1>d:\egyetem\2. félév\programozás alapjai 2\khf\7.hazi\7\7\vector.cpp(125) : error C2143: syntax error : missing ';' before '{'
    1>d:\egyetem\2. félév\programozás alapjai 2\khf\7.hazi\7\7\vector.cpp(125) : error C2447: '{' : missing function header (old-style formal list?)

    Ha a namespace nincs kikommentezve, akkor pedig egy nagyon hosszú hibasort, mely az ostream-re mutat...

    A forráskódok:

    Vector.cpp:
    #include <limits.h>
    #include <assert.h>
    #include <iostream>
    #include "Vector.h"
    #include "string.h"

    using namespace HomeMadeString;

    Vector::Vector(const Vector& theOther)
    {
    pData=NULL;
    *this=theOther;
    }

    void Vector::clear()
    {
    elementNum=0;
    delete [] pData;
    }


    void Vector::erase(unsigned int position)
    {
    assert(position<elementNum);

    if(elementNum==1)
    {
    delete []pData;
    pData=NULL;
    elementNum=0;
    return;
    }

    elementNum--;
    String* pTemp=new String[elementNum];

    for(unsigned int i=0, j=0;i<elementNum+1;i++,j++)
    {
    if(i==position)
    {
    j--;
    }
    else
    {
    pTemp[j]=pData[i];
    }
    }
    delete[] pData;
    pData=pTemp;
    }

    String& Vector::at(unsigned int position)
    {
    assert(position<elementNum);
    return pData[position];
    }

    const String& Vector::at(unsigned int position)const
    {
    assert(position<elementNum);
    return pData[position];
    }

    bool Vector::insert(unsigned int position, String element)
    {
    if(elementNum==UINT_MAX)
    {
    return false;
    }
    if(position<elementNum)
    {
    String* pTemp=new String[elementNum+1];
    for(unsigned int i=0,j=0;i<elementNum;i++,j++){
    if(j==position){
    pTemp[i]=element;
    j--;
    }
    else pTemp[i]=pData[j];
    }
    delete[] pData;
    pData=pTemp;
    elementNum++;
    }
    else{
    String* pTemp=new String[position+1];
    for(unsigned int i=0;i<=position;i++){
    if(i<elementNum)pTemp[i]=pData[i];
    else{
    if(i==position)pTemp[i]=element;
    else pTemp[i]=0;
    }
    }
    delete[] pData;
    pData=pTemp;
    elementNum=position+1;
    }
    return true;
    }
    String & Vector::operator [](unsigned int position)
    {
    return at(position); // Miért nem return pData[position]; ???
    }
    const String & Vector::operator [](unsigned int position)const
    {
    return at(position); // Miért nem return pData[position]; ???
    }

    const Vector& Vector::operator= (const Vector & theOther)
    {
    assert(this!=&theOther);
    delete[] pData;
    elementNum=theOther.elementNum;
    if(elementNum==0) pData=NULL;
    else {
    pData=new String[elementNum];
    for(unsigned int i=0;i<elementNum;i++) pData[i]=theOther.pData[i];
    }
    return *this;


    }
    using namespace std;
    ostream & operator << (ostream& os, const Vector &v)
    {
    for(unsigned int i=0;i<v.elementNum;i++)
    {
    os<<' '<<v.at(i);
    }
    return os;
    }

    Vector.h:
    #ifndef VECTOR_H
    #define VECTOR_H

    #include <iostream>
    #include "string.h"

    // Egy dinamikus tömb osztály
    using namespace HomeMadeString;
    class Vector
    {
    // A tömb mérete
    unsigned int elementNum;
    // Az adatokra mutató pointer
    String *pData;

    // Diagnosztikai célú globális kiiratóoperátor
    friend std::ostream & operator << (std::ostream& os,const Vector& v);

    public:
    // Konstruktorok, destruktor
    Vector() {elementNum=0;pData=NULL;}
    Vector(const Vector& theOther);
    ~Vector() {delete[]pData;}

    // Visszatér a tömb méretével.
    int size()const{return elementNum;}
    // Törli a tömböt (ez konzisztens állapotba is hozza a tömböt, nem csak a dinamikus adatterületet szabadítja fel)
    void clear();
    // Törli a megadott indexu elemet. A 0 és size()-1 közötti indexek érvényesek.
    void erase(unsigned int position);
    // Visszatér a megadott indexu elemmel, amely módosítható is egyben.
    // A 0 és size()-1 közötti indexek érvényesek.
    String& at(unsigned int position);
    // Visszatér a megadott indexu elemmel, amely csak olvasható.
    // A 0 és size()-1 közötti indexek érvényesek. Az int típus esetén nem kellene
    // const referencia, de saját típus esetén igen, lásd házi feladat.
    const String& at(unsigned int position)const;
    // Beszúr egy elemet a megadott indexu helyre.
    // Ha az index nagyobb, mint a tömb mérete, megnöveli a tömb méretét,
    // és a szükséges új helyeket nullákkal tölti fel.
    bool insert(unsigned int position, String element);

    // Operator=
    const Vector& operator= (const Vector & theOther);

    // Két operator[]. Az at() tagfüggvény operator formában is.
    String & operator [](unsigned int position);
    const String & operator [](unsigned int position)const;
    };

    // Diagnosztikai célú kiiratás
    std::ostream & operator << (std::ostream& os, Vector& v);
    #endif /*VECTOR_H */

    String.h:
    #ifndef STRING_H
    #define STRING_H
    #include <iostream> // A coutnak

    namespace HomeMadeString
    {
    class String
    {
    // A karakterek aktuális száma:
    int elementsNum;

    // A karaktereket tartalmazó memóriaterületre mutató pointer:
    char *pData;
    public:
    // Argumentum nélküli konstruktor:
    String();

    // Másoló konstruktor:
    String(const String & string);

    // Egy NULL végu sztringet váró konstruktor
    String(char * str);

    // Egy karaktert és egy elojel nélküli egészet (times) váró konstruktor,
    // amely times darab c karakterrel inicializálja a stringet:
    String(char c, unsigned int times);

    // A destruktor:
    ~String();

    // A string objektum tartalmát a megadott bufferbe másolja, és NULL-lal lezárja
    // (a buffernek a hívó foglal helyet):
    void getStr(char * pBuff);

    // Visszatér a sztring hosszával
    unsigned int getLength(){return elementsNum;}

    // Kiírja a sztringet a megadott kimeneti adatfolyamba (A 'cout' ostream típusú.
    // A .h állományban nem használunk using namespace-t, mert nem tudjuk, hova lesz
    // beépítve, és ott milyen hatása lesz. Ezért kiíjuk az std::-t. Ez a .cpp állományban
    // már nem kell, ot használhatjuk a using namespace std utasítást):
    void print(std::ostream& os);

    // Visszaadja a megadott pozícióban lévo karaktert, egyébként nullát:
    char getChar(unsigned int pos);

    // --- Statikus függvények. Ezek két stringen végeznek muveletet. ---

    // Összefuz két sztringet, és visszatér vele:
    static String concatenate(const String& string1,const String& string2);

    // Összehasonlít két sztringet:
    static bool compare(const String& string1,const String& string2);

    // A második sztringet az elso sztringbe másolja:
    static void copy(String& string1,const String & string2);
    };
    }
    #endif /* STRING_H */

    String.cpp:

    #include <iostream>
    #include <locale>
    #include <string.h>
    #include "String.h"

    using namespace std;
    using namespace HomeMadeString;

    String::String()
    {
    elementsNum=0;
    pData=NULL;
    }

    String::String(const String & string)
    {
    int i;
    this->elementsNum=string.elementsNum;
    this->pData=new char[elementsNum];
    for (i=0;i<elementsNum;i++)
    pData[i]=string.pData[i];
    pData[i]='\0';
    }

    String::String(char *str)
    {
    int i;
    for (i=0;str[i];i++);
    elementsNum=i;
    pData=new char[i];
    for (i=0;str[i];i++)
    pData[i]=str[i];
    pData[i]='\0';
    }

    String::String(char c, unsigned int times)
    {
    int i;
    elementsNum=times;
    if (!times)
    pData=NULL;
    else
    {
    pData=new char [times];
    for (i=0;i<elementsNum;i++)
    pData[i]=c;
    pData[i]='\0';
    }
    }

    String::~String()
    {
    //delete[] pData;
    }

    void String::getStr(char *pBuff)
    {
    int i;
    for (i=0;pData[i];i++)
    pBuff[i]=pData[i];
    pBuff[i]='\0';
    }

    char String::getChar(unsigned int pos)
    {
    if (elementsNum>pos)
    return pData[pos];
    else
    return 0;
    }

    String String::concatenate(const String& string1,const String& string2)
    {
    String str;
    str.elementsNum=string1.elementsNum+string2.elementsNum;
    str.pData=new char[str.elementsNum];
    int i,j;
    for (i=0;string1.pData[i];i++)
    str.pData[i]=string1.pData[i];
    for (j=0;string2.pData[j];j++)
    str.pData[i+j]=string2.pData[j];
    return str;
    }
    bool String::compare(const String& string1,const String& string2)
    {
    if (!(strlen(string1.pData)==strlen(string2.pData)))
    return false;
    for (int i=0;i<string1.elementsNum;i++)
    if (!(string1.pData[i]==string2.pData[i]))
    return false;
    return true;
    }

    void String::copy(String & string1,const String & string2)
    {
    delete[] string1.pData;
    string1.elementsNum=string2.elementsNum;
    if (!string1.elementsNum)
    string1.pData=NULL;
    else
    {
    string1.pData=new char[string1.elementsNum];
    int i;
    for (i=0;string2.pData[i];i++)
    string1.pData[i]=string2.pData[i];
    }
    }

    void String::print(std::ostream & os)
    {
    for (int i=0;i<elementsNum;i++)
    os<<pData[i];
    }

    És a tesztelésre használt VectorSample.cpp:
    #include "Vector.h"
    #include "String.h"

    using namespace std;
    int main()
    {
    Vector v1;

    // Insert tesztelése
    for(int i=1;i<10;i++)
    {
    v1.insert(i,"i");
    }

    // A kiírás (operator<<) és az at() függvény tesztelése
    cout<<v1<<endl;
    //Helyes eredmény:
    // 0 1 2 3 4 5 6 7 8 9

    // Másoló konstruktor
    Vector v2(v1); // Lehetne: Vector v2=v1;
    // op=
    Vector v3;
    v3=v2;

    // Megváltoztatjuk v1-t (erase tesztelése)
    v1.erase(0);
    // v1.erase(9); //Ennek assertelni kell

    cout<<endl<<v1<<endl<<v2<<endl<<v3<<endl;
    // Helyes eredmény:
    // 1 2 3 4 5 6 7 8 9
    // 0 1 2 3 4 5 6 7 8 9
    // 0 1 2 3 4 5 6 7 8 9

    v2.insert(0,"-1");
    cout<<v2<<endl;
    // Helyes eredmény:
    // -1 0 1 2 3 4 5 6 7 8 9

    v2.insert(10,"-1");
    cout<<v2<<endl;
    // Helyes eredmény:
    // -1 0 1 2 3 4 5 6 7 8 -1 9

    v2.insert(12,"-1");
    cout<<v2<<endl;
    // Helyes eredmény:
    // -1 0 1 2 3 4 5 6 7 8 -1 9 -1

    v2.insert(15,"-1");
    cout<<v2<<endl;
    // Helyes eredmény:
    // -1 0 1 2 3 4 5 6 7 8 -1 9 -1 0 0 -1

    v2[15]="-2";
    cout<<v2<<endl;
    // Helyes eredmény:
    // -1 0 1 2 3 4 5 6 7 8 -1 9 -1 0 0 -2

    // v2[16]=3; //Ennek assertelni kell

    return 0;
    }

    Kérem valaki segítsen nekem, már több órája ezzel harcolok, de nem jövök rá, hogy mi a probléma. :S

    Üdvözlettel: Papa

  • sghc_toma

    senior tag

    válasz WonderCSabo #701 üzenetére

    legjobb tudomasom szerint szep modszer nincs ra, de a clear + str("") kombonak mukodnie kellene.. az, hogy nem tudsz bele irni, mit jelent? hibat dob, vagy csak siman ures marad a stream?
    esetleg meg megprobalhatod, hogy torlod az error flag-eket, es a put/get pointereket meg beallitod a stream elejere:

    stringstreamneve.clear();
    stringstreamneve.seekp(0);
    stringstreamneve.seekg(0);

    "Ha csak cleart használok, nem csinál semmit"
    nem meglepo, a clear az error flag-eket allitja be...

  • mgoogyi

    senior tag

    válasz Jhonny06 #694 üzenetére

    Egyrészt ezt így próbáld ki, nekem így simán működik:

    #include <stdio.h>
    #include <iostream>
    #include <fstream>
    #include <string>

    using namespace std;

    struct example
    {
    int day;
    string name;
    };

    typedef example array[5];

    int load(int& counter, array something);
    int write(array something);

    int main()
    {
    int counter;
    array something;
    load(counter, something);
    write(something);

    getc(stdin);
    return 0;
    }

    int load(int& counter, array something)
    {
    ifstream file;
    file.open("file.txt");
    file >> counter; //<- #2 PROBLEM
    for(int i=0; i<counter; i++)
    {
    file >> something.day;
    file >> something(i).name;
    cout << something(i).day << " " << something(i).name << endl;
    }
    file.close();
    return 0;
    }

    int write(array something)
    {
    int one=1;
    if(something[one].day)
    cout << something[one].name; //<- #1 PROBLEM
    /*else
    continue;*/
    return 0;
    }

    Referencia, cím, stb:

    ha van egy tömböd, pl. int tomb[5];
    akkor ha csak simán ezt írod le, hogy pl(sorry a c-s kiíratásért, én azt szeretem):
    printf("%d",tomb); -> a tömb memóriacíme
    tomb[0] -> a tomb memóriacíménél lévő int elem
    tomb[1] -> a tomb címéhez képest egy inttel arrébb lévő elem
    tomb[2] -> a tomb címéhez képest két inttel arrébb lévő elem

    tomb + 0 -> a tomb első elemének, avagy a tömbnek a memóriacíme
    tomb + 1 -> a tomb második elemének a címe

    *(tomb + 0) -> a * rámutat a zárójelben lévő címre, azaz az ottani int értéket jelenti

    az és(&) jel több dologra jó, most kettőre térek ki:

    1. Cím lekérése
    van egy ilyen változód, hogy:
    int i = 5;
    &i ennek az i változónak a címét jelenti a memóriában.
    Ha pointerezel: *(&i) az i címére mutató pointer, tehát maga az i.

    2. Referencia (nem tudom milyen nyelvekben vagy jártas, pascalban pl. ez a var kulcsszó, ill. sok nyelvben meg mindig referencia szerinti átadás van, mint pl. java - persze vannak kivételek:))

    int i = 5;
    int & j = i; // az i "álneve" vagy "aliasa" j lesz

    itt a j egy és ugyanaz a változó, mint az i, tehát ha ezt csinálod, hogy
    j = 6;
    akkor az i is 6 lesz, mivel a két változó ugyanaz, csak két különböző néven tudod őket elérni.

    ha van egy függvény, ami referenciát vár, pl:

    void inc (int & j) {
    j++;
    }

    int i = 5;
    inc (i);

    akkor ennek a függvénynek a paramétere egy alias lesz i-re, tehát ha a függvényben megváltoztatod j-t, azzal i-t változtatod. Szal a referencia arra van általában, hogy a bemeneti paraméter kimeneti is lehessen ill. még azért használják, mert ez egy dereferált pointer a beadott paraméterre és ha az a paraméter nagyobb helyet foglal, mint egy pointer, akkor nem kell lemásolni a beadott értéket az újonnan létrehozott ugyanolyan nagy paraméterváltozóba. Ha az utóbbi félmondatot még nem érted, nem nagy gond.

    Szóval te egy függvénynek átadtad referenciaként egy tömb címét. Ezt a címet te nyilván nem akarod megváltoztatni, mert akkor a memóriában ki tudja honnan olvasnál be dolgokat.
    Kíváncsi vagyok, hogy ebből mit értettél meg... :DDD

  • doc

    nagyúr

    válasz kissgy04 #510 üzenetére

    1. Ha azt írom, hogy f$Stop ? 0 : az miben más a fenti f$Stop==1 ? 0 :
    annyiban, hogy az elso esetben azt vizsgalod, hogy nullatol kulonbozo-e, a masodikban azt, hogy pontosan egy-e

    2. f$Stop==0 az más mint az !f$Stop, és ha igen miben?
    tulajdonkeppen nem, a ! annyibol mas mint a ==0, hogy pl. NULL pointerre is igazat ad vissza (bar az C++ forditok a 0-t is ertelmezni szoktak pointerre, NULL-kent)

  • doc

    nagyúr

    válasz martonx #474 üzenetére

    szerintem ez sokkal inkabb volt nyelvi kerdes mint algoritmikus (pointerek, tombok, stb), ha mar mindenaron bele akarsz kotni, akkor abba hogy ez inkabb C mint C++ :)

  • Lortech

    addikt

    válasz sekli #308 üzenetére

    Azza a sorral van pedig gond, amit a kolléga említett. Miért int*? EZ itt nagyon nem frankó: (char *) &m, sizeof (m) - csinálsz egy char * pointert az int tömbödből csaz azért hogy tudjál bele olvasni, erre elkezdi behányni a karaktereket az int tömbbe a címtől kezdve. Meg a sizeof is nem tudom, mi célt szolgál itt, ha arra gondoltál, nem a tömb méretét (elemszámát) adja meg, hanem a típusét bájtban.

    int bufferm = 20;
    char * m = new char[bufferm];
    cout << "kezd ";
    in.read(m, bufferm);
    for(int i = 0; i <bufferm; i++) // show values read from file
    cout << m[i] << " ";
    in.close();

  • steveetm

    őstag

    válasz sekli #308 üzenetére

    Akkor mindenképp ajánlom ezt: [link]

    Az ok, hogy dinamikusan foglalsz helyet, de arra mérget vehetsz, hogy a sizeof(m) a pointered méretét fogja megadni, ami nem nagyon lesz több 4nél.
    *hint*

    int* m ->sizeof(m)=4;
    int m[10] -> sizeof(m)=40;

    Üdv.: steveetm

  • steveetm

    őstag

    válasz sekli #305 üzenetére

    Igen, de valszeg nem emiatt. Ha már *m ed van akkor pointer, így beolvasásnál fölösleges még 1 &, mert így csak a mutatód címét kapnád meg. Az m ebben az esetben már egyenlő az előző verziód &m jével(mod.: mármitn nem egyenlő, értékileg, de érted, na(bár akár lehetne is, de most picit elkalandoztam a lényegtől)) , ennek szellemében alakítsd át még a második verziót.

    ui.: rég láttam már tipusos nyelveket, szal ha hülyeséget mondok most akkor sry, de imho ez a gond^^
    Üdv.: steveetm

  • atm*RefeeZ

    tag

    válasz Jester01 #261 üzenetére

    hát nekem cpp kiterjesztést csinál,a program neve is c++ úgyhogy nem tudom akkor kit hol vernek át:(

    a strcpy(m,mail); kikerült belőle,igazából rájöttem,hogy butaságot írtam,sajnos a drága tanárunk úgy gondolta,hogy háát..úgy sem értek c-hez,nem megyek bele hogy a sok hülyének megpróbálom előadni mit jelent az,hogy pointer,mikor mire mutat stb...így egyedül kellene megérezni ami egyenlőre nincs meg,de igyekszem:)

    köszönöm szépen:)

  • k.t.a.

    senior tag

    válasz k.t.a. #254 üzenetére

    Ebben nincs semmilyen visszatérési érték sem, de nincs is rá szükség. Egyszerően a függvényedből egy globális változót modosítgatsz. Azért nem lehet stringet visszaadni értéknek, mert a string egy karakterre mutató pointer, és amikor ezt akarnád visszatérési értéknek adni, akkor csak egy olyan címet kapnál amin már nincsen semmi. Azért mert amit kiszámolsz a függvényedben az egy lokális változóban lenne tárolva, és ez törlődik amikor meghívod return-t. Ergo csak egy üres memória helyre mutató címet kapnál.

  • atm*RefeeZ

    tag

    hello

    olyan függvényt akarok írni ami egy stringet ad vissza. azt mondták hogy ezt pointerrel lehet megtenni. kérdem én, hogyan?elég sűrgős lenne:)

    köszi előre is.

  • caddie

    csendes tag

    1, Osztalyon kivul definicio:
    - letisztult marad az osztaly interface ( kod olvashatosag )
    - tipikusan kulon header / forras fileokba rendezzuk az osztaly deklaraciot es definiciot, hogy az osztaly implementaciojanak megvaltoztatasakor ne kelljen ujraforditani mindne olyan forrasfilet, amely csak az interface-tol fugg (erre vannak meg szofisztikaltabb modellek is pl: pimpl idiom)
    - C++ -ban az a szokas, hogy az inline fuggvenyeket definialjuk osztalyon belul, amelyek 1-2 sorosak, a tobbit pdig osztalyon kivul definialjuk


    2, using namespace std;

    - ezt alapbol nem ajanlott hasznalni, mert az std nevterben levo osszes elerheto nevet beemeli, helyette specifikusan a hasznalt neveket szokas / vagy meginkabb minositeni szokas a hasznalt dolgokat
    - ha header file-ba irod be, akkor az osszes forrasfile amely felhasznalja a headert keretlenul is megkapja az osszes std nevterben levo elerheto nevet
    - nevtereket pont azert talaltak ki, hogy particionalva legyenek (felosztva) a nevek. using namspace std beemelesevel pont ezt iktatjuk ki, hiszen minden beemelunk a ''globalis'' nevterbe


    3, inicializalasi lista:

    - amikor a konstruktor torzsebe adod meg, hogy adott member valtozonak milyen kezdoerteket szeretnel megadni, akkor eloszor letrejon az objektum, lefut a default konstruktora, majd egy kulon fuggvenyhivas kereteben masolodik at a kezdoertek. inicializalasi listaval az adott valtozo konstrualasakor mar kezdoertekkel latod el azt (tehat hatekonyabb es igy az elegans, erre talaltak ki az inicializalasi listat).


    4, size_t: STL az egy peldas kod, erdemes annak a filozofiaja szerint dolgozni, annak eszkozeit hasznalni es amennyire ertelmes idomulni hozza.

    5. NULL nincs benne a C++ szabvanyban, teljesen forditofuggo, hogy van-e benne, mi van mogotte (makro) es hogy a fordito kov. verziojaban is benne lesz-e. amugya 0 -nak implicit konverzioja van pointerekre.

    6. a postfix novelo operatorok definicio szerint egy temporalis objektumba mentik a valtozo eredeti erteket, majd megnovelik a valtozo erteket, a regi erteket pedig visszadjak. a prefix novelo operator cask novel es visszaad, ergo a postfix min 2x annyi muveletet vegez (szamszeruleg, valoszinuleg a fordito ugyanis kioptimalizalja). A lenyeg, hogy prefix kell mindenhova kiveve ahova postfix kell :)


    Roviden ennyi, remelem nem hagytam ki semmit

  • caddie

    csendes tag

    válasz Zulfaim #140 üzenetére

    Hat a kod sok-sok sebbol verzik:

    - buff = ' 'zzz' ' ez mi ez?, miert nem hasznalsz inicializalasi listat?
    - kiiro operatornak nyugodtan lehet const buffer& -t atadni
    - += operatornt - minimalisan - igy modositanam:

    )
    buffer& buffer:: operator+=( const char* value)
    {
    char* temp=new char[size = strlen(buff)+ strlen(value) +1];
    strcpy(temp,buff);
    strcat( temp, value);
    delete[] buff;
    buff = temp;
    return *this;
    }


    teljesen feleslegesen masolgatsz es foglalsz memoriat. Jelen pillanatban nem ellenerozom, hogy az atadott pointer null pointer / van legalabb 1 karkater benne stb. Ezt belehekkelheted.

    - ertekado operatornal, bevallom nem ertem ezt:

    for(int i=0;i<size;i++)
    {
    buff=e.buff;
    }


    ez mi ez?

    talan

    for(int i=0;i<size;i++)
    {
    buff [ .i. ] =e.buff [ .i. ] ; // konvertalas miatt :(
    }


    ? De ez sem jo, mert a vegere nem masolja oda a '/0' -t. Sztem erdemesebb lenne hasznalni a strcpy-t

    - kiiro operator hasonloan beteg

    - nem latok racionalis okot, hogy meirt van a += es az egyik ertakado operator az osztalyon belul definialva, a tobbi meg kivul.

    - copy konstruktor is beteg, keves memoriat foglalsz es utana u.a. a hulyeseg van mint ertakado operatornal

    - sztem teljsen feleslegesen a postfix incerementalo operatorok

    [Szerkesztve]

  • amargo

    addikt

    válasz Ramius #113 üzenetére

    A Scanf-el is meg lehet csinálni, csak én már untam, hoyg annyi mindent kell lekezelni sokszor.. Pointerekkel lehetne még igazán jól lekezelni a dolgot, hogy ne is legyen pazarló, de amilyen szinten a tanárok elvárják, ahhoz most ez is jó:

    //---------------------------------------------------------------------
    bool IsDigit(char ch)
    {
    return ((ch >= '0' && ch <= '9') || ch == '.');
    }//bool IsDigit(char ch)
    //---------------------------------------------------------------------
    template <class Var>
    void getNum(Var &n, Var lob, Var hib) //lob az alsó határ
    {
    bool error;
    do
    {
    string str;
    n = 0;
    error = false;
    cin >> str;
    for(int h = 0; h < (signed)str.length(); h++)
    {
    if(!IsDigit(str[ h ]) || str[ 0 ] == '-' )
    {
    error = true;
    cout << ''Hiba, Szamot adjon meg!\n'' << endl;
    break;
    }
    }
    if(!error)
    {
    n = (Var)atoi(str.c_str());
    }
    if((n < lob || n >= hib) || error) //Nem engedjük meg a hib-ig menni és a lob-nál nagyobbnak kell lennie!
    {
    cout << ''Hibas a bevitt ertek\n'' << lob << '' -tol, '' << hib << '' -ig. Adja meg a szamot.'' << endl;
    error = true;
    }
    }while( !(lob <= n) || error);
    }//int getNum()


    Szerk: az előnye, hogy lebegőpontos számokat is képes kezelni.. Nem kell hozzá átírkálni.

    [Szerkesztve]

  • Zulfaim

    csendes tag

    Szevasztok!

    Bufferelten kezelt fájlt kellene írnom c++-ban OO-an.
    Csináltam egy buffer osztályt, ahol tárolok egy pointert és a méretet.
    Ennek kéne működnie:
    buffer+=szoveg;

    ahol mindketten string-et tároló tömbök.
    a szoveget is úgy tárolom, hogy pointer+méret, de azt a main()-ben hozom létre.
    Ezt operátor overloaddal kéne megoldani, de nem tudom hogy.
    Tudna valaki segíteni?

  • ktg3

    őstag

    vki segítesen legyen szíves!!!

    combos kis hsz lesz...
    szokásszerint megint nem tudom h hol a hiba
    biztos lesz benne egy rahedli..

    amig nem írtam meg az utólsó 4 fgv-t addig működött jól..
    szal ott keresendő a hiba!

    köszönöm!

    //string.h


    #ifndef STRING_H
    #define STRING_H
    #include <iostream>
    namespace TheUltimateString
    {
    class String
    {
    // A karakterek aktuális száma:
    unsigned int elementsNum;

    // A karaktereket tartalmazó memóriaterületre mutató pointer:
    char*pData;
    public:
    // Argumentum nélküli konstruktor:
    String();

    // Másoló konstruktor:
    String(const String&string);

    // Egy NULL végu sztringet váró konverziós konstruktor
    // Ez felel a char*-> String konverzióért
    String(const char* str);

    // Egy karaktert és egy elojel nélküli egészet (times) váró konstruktor,
    // amely times darab c karakterrel inicializálja a stringet:
    String(char c, unsigned int times);

    // A destruktor:
    ~String(){delete[]pData;}

    // Visszatér a sztring hosszával
    unsigned int getLength()const{return elementsNum;}

    // Kiírja a sztringet a megadott kimeneti adatfolyamba (a 'cout' ostream típusú):
    void print(std::ostream& os);

    // Visszaadja a megadott pozícióban lévo karaktert, egyébként nullát:
    char& operator[](unsigned int pos);
    // Konstans objektumokat is le szeretnénk kérdezni
    const char& operator[](unsigned int pos)const;

    // Összefuz két Stringet
    String operator+(const String& theOther)const;
    const String& operator+=(const String &theOther);
    const String& operator=(const String& theOther);
    bool operator==(const String& theOther)const;
    bool operator!=(const String& theOther)const;


    // Visszaad egy csak olvasható hozzáférést a stringhez
    operator const char*()const;

    // --- Statikus függvények. Ezek két stringen végeznek muveletet. ---

    // Összefuz két sztringet, és visszatér vele:
    static String concatenate(const String& string1, const String& string2);

    // Összehasonlít két sztringet:
    static bool compare(const String& string1, const String& string2);

    // A második sztringet az elso sztringbe másolja:
    static void copy(String& string1, const String &string2);

    unsigned int strlen(const String& s);

    int strchr(const String& s,char c);

    bool strcmp(const String& s1,const String& s2);

    char* strstr(const String& s1,const String& s2);
    };
    }
    #endif /* STRING_H */





    //string.cpp


    #include ''String.h''
    using namespace std;
    using namespace TheUltimateString;
    // Argumentum nélküli konstruktor:
    String::String()
    {
    elementsNum=0;
    pData=new char[1];
    pData[0]='\0';
    }
    // Másoló konstruktor:
    String::String(const String& string)
    {
    *this=string;
    }
    // Egy NULL végu sztringet váró konverziós konstruktor
    // Ez felel a char*-> String konverzióért
    String::String(const char* str)
    {
    elementsNum=strlen(str);
    pData=new char[strlen(str)+1];
    for(unsigned int i=0;i<strlen(str)+1;i++)
    pData=str;

    }
    // Egy karaktert és egy elojel nélküli egészet (times) váró konstruktor,
    // amely times darab c karakterrel inicializálja a stringet:
    String::String(char c, unsigned int times)
    {
    elementsNum=times;
    pData=new char[elementsNum+1];
    for(unsigned int i=0;i<elementsNum;i++)
    pData=c;
    pData[elementsNum]='\0';
    }
    // Kiírja a sztringet a megadott kimeneti adatfolyamba (a 'cout' ostream típusú):
    void String::print(ostream& os)
    {
    os<<pData<<endl;
    }
    // Visszaadja a megadott pozícióban lévo karaktert, egyébként nullát:
    char& String::operator[](unsigned int pos)
    {
    return pData[pos];
    }
    // Konstans objektumokat is le szeretnénk kérdezni
    const char& String::operator[](unsigned int pos)const
    {
    return pData[pos];
    }
    // Összefuz két Stringet
    String String::operator+(const String& theOther)const
    {
    String s;
    s.pData=new char[elementsNum+theOther.elementsNum+1];
    for(unsigned int i=0;i<elementsNum;i++)
    s.pData
    =pData;
    for(i=0;i<theOther.elementsNum;i++)
    s.pData[i+elementsNum]=theOther.pData
    ;
    s.elementsNum=elementsNum+theOther.elementsNum;
    s.pData[s.elementsNum]='\0';
    return s;
    }
    const String& String::operator+=(const String &theOther)
    {
    char* tmp=new char[elementsNum+theOther.elementsNum+1];
    for(unsigned int i=0;i<elementsNum;i++)
    tmp=pData;
    for(i=0;i<theOther.elementsNum;i++)
    tmp[i+elementsNum]=theOther.pData;
    this->elementsNum+=theOther.elementsNum;
    tmp[elementsNum]='\0';
    delete[]pData;
    this->pData=tmp;
    return *this;
    }
    const String& String::operator=(const String& theOther)
    {
    elementsNum=theOther.elementsNum;
    pData=new char[theOther.elementsNum+1];
    for(int i=0;i<theOther.elementsNum;i++)
    pData
    =theOther.pData;
    pData[elementsNum]='\0';
    return *this;
    }
    bool String::operator==(const String& theOther)const
    {
    if(elementsNum!=theOther.elementsNum)
    return false;
    else
    {
    int not=0;
    for(int i=0;i<elementsNum;i++)
    {
    if(pData
    !=theOther.pData)
    {not=1; break;}
    }
    if(not) return false;
    else return true;
    }
    }
    bool String::operator!=(const String& theOther)const
    {
    if(theOther==*this)
    return false;
    else return true;
    }
    // Visszaad egy csak olvasható hozzáférést a stringhez
    String::operator const char*()const
    {
    return pData;
    }
    // --- Statikus függvények. Ezek két stringen végeznek muveletet. ---
    // Összefuz két sztringet, és visszatér vele:
    String String::concatenate(const String& string1, const String& string2)
    {
    String s;
    s.elementsNum=string1.elementsNum+string2.elementsNum;
    s.pData=new char[s.elementsNum+1];
    for(int i=0;i<string1.elementsNum;i++)
    s.pData
    =string1.pData;
    for(i=0;i<string2.elementsNum;i++)
    s.pData[string1.elementsNum+i]=string2.pData
    ;
    return s;
    }
    // Összehasonlít két sztringet:
    bool String::compare(const String& string1, const String& string2)
    {
    if(string1.elementsNum!=string2.elementsNum)
    return false;
    else
    {
    int not=0;
    for(int i=0;i<string1.elementsNum;i++)
    {
    if(string1.pData!=string2.pData)
    {not=1; break;}
    }
    if(not) return false;
    else return true;
    }
    }
    // A második sztringet az elso sztringbe másolja:
    void String::copy(String& string1, const String &string2)
    {
    string1.elementsNum=string2.elementsNum;
    string1.pData=new char[string2.elementsNum+1];
    for(int i=0;i<string2.elementsNum+1;i++)
    string1.pData=string1.pData;
    }

    unsigned int String::strlen(const String& s)
    {
    return s.elementsNum;
    }
    int String::strchr(const String& s,char c)
    {
    for (int i=0;i<s.elementsNum;i++)
    if (s.pData==c)
    return i+1;
    }
    bool String::strcmp(const String& s1,const String& s2)
    {
    if (s1.elementsNum==s2.elementsNum)
    for (int i=0;i<s1.elementsNum;i++)
    {
    if (s1.pData
    !=s2.pData)
    return false;
    if (i==s1.elementsNum-1)
    return true;
    }
    else return false;
    }
    char* String::strstr(const String& s1,const String& s2)
    {
    char* s=''nincs benne/0'';
    char* string2=new char [s2.elementsNum+1];
    for (int i=0;i<s2.elementsNum;i++)
    string2
    =s2.pData;
    string2[s2.elementsNum]='/0';


    for (i=0;s1.elementsNum;i++)
    {
    if (s1.pData
    ==s2.pData[0])
    {
    for (int j=0;j<s2.elementsNum;j++)
    {
    if (s1.pData[j]!=s2.pData[j])
    return s;
    if (j==s2.elementsNum-1)
    return string2;
    }
    }
    }
    }



    //theultimatesample.cpp


    #include <iostream>
    #include ''String.h''

    using namespace std;
    using namespace TheUltimateString;


    int main()
    {
    String str1=''Hello Moneypenny.'';
    printf(str1);
    str1=''My name is Bond. '';
    str1+=''James Bond.'';
    printf(''\n%s\n'',(const char*)str1);

    if(str1==(String)''My name is Bond. James Bond.''
    &&!(str1!=(String)''My name is Bond. James Bond.''))
    {
    cout<<''Oh, Mr. Bond!''<<endl;
    }

    return 0;
    }


    belefért :U

  • bpx

    őstag

    válasz Retekegér #87 üzenetére

    c++ ban van string típus, nem kell pointerezni, nem kell format-stringezni

Új hozzászólás Aktív témák

Hirdetés