Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailem C++ - Spojový seznam - nefunkční Find() a problém s výjimkami

Tak, po frontě jsem tu zas, a se seznamem :D Věc se má tak, že mi z nějakého důvodu nefunguje fce Find, problém dělá přiřazení node=node->next, kde se do node přiřadí 0, ale netuším proč - předpokládal jsem, že když na začátku fce do node přiřadím first, budu moct manipulovat přes node i s nexty...

Tady je kód: mafpzl35-18993

A ohledně výjimek... Pokud mám třeba fci First, která vrací data z hlavy, tak musím ošetřit situaci, kdy je hlava NULL. Normálně jsem to řešil vracením "nepravděpodobné hodnoty", třeba -1, ale to není ok, protože pokud by v hlavě bylo uložené totéž číslo, je s tím problém... Proto jsem chtěl použít nějakou výjimku, která by mi umožnila nevracet nic a vypsat na obrazovku krátkou hlášku o chybě. Bohužel, fprintf(stderr, error) vypíše hlášku, ale za ni ještě počet vytištěných znaků, což mi ve výpisu vadí. Zkusil jsem tedy try-catch, ale tam zase dochází k okamžitému ukončení programu po vytištěné hlášce, popř. to vrací 0 - co s tím? Kód Firstu s výjimkou je zde:

int List::First(){
    try{
        if(!first){
            throw new ListEmptyError();
        }else{
            return first->data;
        }

    }catch(...){
        cout <<  endl;
    }
}

Opět moc díky za rady, snad už mých dotazů bude postupně ubývat :D

Jsou zobrazeny jen nové odpovědi. Zobrazit všechny
Předmět Autor Datum
Ok, Add_First jsem přepsal takhle: void List::Add_on_first(int data){ item *node = new item; //vytv…
Katsushiro 04.06.2013 15:52
Katsushiro
Este tam vidim jeden potencialny problem a to ze ak pri mazani prvku vymazes posledny prvok tak nena…
MM.. 04.06.2013 15:54
MM..
Tak, last jsem ošetřil, teď koukám na ten try-catch. Povedlo se mi to vyřešit takto: Definice fce:…
Katsushiro 04.06.2013 18:52
Katsushiro
Ked ma fcia vracat hodnotu tak musi vratit hodnotu, ked ziadnu nema tak musi skocit mimo funkci. Ina… poslední
MM.. 05.06.2013 11:37
MM..
No, objevil se další problém, který jsem nečekal ani já :D Vytvořil jsem funkci Del_last, která by m…
Katsushiro 05.06.2013 11:05
Katsushiro
necital som cely program ale ked urobis last = last->prev; tak nemozes vediet ze ci ten last teraz n… nový
MM.. 05.06.2013 11:19
MM..

Ok, Add_First jsem přepsal takhle:

void List::Add_on_first(int data){
    item *node = new item; //vytvorim objekt

    //inicializuji objekt
    node->data = data;
    node->next = NULL;
    node->prev = NULL;

    if(first == NULL){
        first = node;
        first->next = NULL;
        first->prev = NULL;

        if(last == NULL){
            last = first;
        }

    }else{
        item *temp; //pro provazani noveho a byvaleho "first"
        temp = first;

        first->prev = node;

        first = first->prev;
        first->next = temp;
        first->prev = NULL;

    }
}

Vypadá to, že Find už funguje - jdu mrknout na try-catch :D

Edit: Kontroluješ rychleji, než já stíhám přemýšlet :D

Tak, last jsem ošetřil, teď koukám na ten try-catch. Povedlo se mi to vyřešit takto:

Definice fce:

class ListEmptyError{
public:
    ListEmptyError(){
        cout << "LEE!";
    }
};

int List::First(){
    if(first){
        return first->data;
    }

    throw ListEmptyError();
};

Volání fce v mainu:

    try{
        cout << a.First() << endl; //LEE
    }catch(...){
        cout << endl;
    }

Takhle to funguje, jak bych chtěl, ale napadá mě, jestli by to nešlo řešit nějak elegantněji, ideálně už v rámci funkce?

Ked ma fcia vracat hodnotu tak musi vratit hodnotu, ked ziadnu nema tak musi skocit mimo funkci.
Inac sa to da len tak ze si zadefinujes funkci tak ze nevraca hodotu ale nejaky status a hodotu bude plnit do nejakej adresy, napr.

BOOL DajData(int* pInt)
{
 if(mam_data)
 {
  *pInt=data;
  return TRUE
 }
 else
  return FALSE;
}

main()
{
 int i;
 if(DajData(&i))
   cout << i;
 else
   cout << "nemam data"
}

k tomu ale potom nepotrebujes ziadne exceptions, a je to komplikovane testovat to furt po kazdom volani fcie, viz moja uplne prva odpoved. Do try-catch bloku mozes uzavret aj 10volani fcie a nasledne urobit osetrenie chyby len na jednom mieste, tym padom zdrojak neni preplneny ifmi a program je prehladnejsi.
P.S> nemaju vas to nahodou ucit v skole? :D Zdravim neschopnych pedagogov :)

No, objevil se další problém, který jsem nečekal ani já :D Vytvořil jsem funkci Del_last, která by měla mazat poslední prvek seznamu, a tedy i fungovat hodně podobně jako Del_first... Problém je, že pokud ji zavolám, a seznam je pak prázdný, následující find při "throw" nahlásí Segmentation fault. Fakt už nevím proč, kód Del_last vypadá takto:

void List::Del_last(){
    if(last == NULL){
        cout << "Seznam je prazdny!" << endl;
    }else{
        item *del;

        del = last;

        last = last->prev;
        last->next = NULL;

        delete del;

        if(last == NULL){
            first = NULL;
        }
    }
}

Celý kód pak vypadá takhle: ktblte55-19005

Opět moc díky za rady, je to nějak náročné :D

necital som cely program ale ked urobis
last = last->prev;
tak nemozes vediet ze ci ten last teraz neni NULL takze nemozes na tu adresu na ktoru ukazuje last pristupovat len tak
last->next = NULL;
ale musis najprv otestovat ci last neni null a pristupovat na tu adresu mozes len ak last neni NULL. Ak je null a chces na tu adresu cosi zapisovat tak "program proved neplatnou operaci". T.j. nemozes menit next u neexistujuceho prvku.
A neni to narocne :)

Zpět do poradny Odpovědět na původní otázku Nahoru