Problem z obsługą wyjątków

Odpowiedz Nowy wątek
2019-06-10 16:04
0

Pisze program, który ma za zadanie wyświetlać ip zależnie od dwóch parametrów konstruktora. Pierwszy parametr to nasze ip gdzie 3 ostatnie cyfry muszą być potęgą liczby 2. Drugi parametr odpowiada za ilość wyświetlanych ip'ków (int scope) i również musi być potęgą liczby 2. W trzecim jest źle podany drugi argument. Natomiast w czwartym źle są podane 3 ostanie cyfry, bo 138 nie jest potega 2, więc powinien wyświetlić się wyjątek. Kiedy próbuje to skompilować wywala mi błąd w 56 linijce:

Nieobsłużony wyjątek w lokalizacji 0x74DEC762 w Project9.exe: wyjątek języka Microsoft C++: std::basic_string<char,std::char_traits<char>,std::allocator<char> > w lokalizacji pamięci 0x010FFA94.: wystąpił wyjątek

Ktoś rozumie jak to naprawić?

Kod:



```#include<iostream>
#include<string>
#include<cstdlib>

using namespace std;

class IP {
protected:
    string ip;
    int scope;
public:
    IP(string ip, int scope) {
        this->ip = ip;
        this->scope = scope;
    };
    int getPieceIP(){
        string pieceIp = ip.substr(12, 3);
        int numPieceIp = atoi(pieceIp.c_str());

        int powOfTwo = 2;
        while (numPieceIp >= powOfTwo) {
            if (numPieceIp == powOfTwo) {
                return numPieceIp;
            }
            else powOfTwo = powOfTwo * 2;
        }
        if (numPieceIp < powOfTwo) {
            string wyjatek = "invalid IP number";
            throw wyjatek;
        }

    }
    string getNewIP(int a) {
        string mainIP = ip.substr(0, 12);
        string newIP = mainIP + to_string(a);
        return newIP;
    }
    void printIP(){
        int pieceIP = getPieceIP();
        int powOfTwo = 2;
        while (scope >= powOfTwo) {
            if (powOfTwo == scope) {
                while (scope != 0) {
                    cout << getNewIP(pieceIP) << endl;
                    ++pieceIP;
                    --scope;
                }
                cout << endl;

            }
            else powOfTwo = powOfTwo * 2;
        }
        if (scope < powOfTwo) {
            string wyjatek = "invalid range";
            throw wyjatek;
        }
    }

};

int main() {
    IP *ip1 = new IP("212.111.212.128", 2);
    IP *ip2 = new IP("212.112.212.128", 4);
    IP *ip3 = new IP("212.113.212.128", 6);
    IP *ip4 = new IP("212.114.212.138", 4);

    ip1->printIP();
    ip2->printIP();
    try
    {
        ip3->printIP();
    }
    catch (string w)
    {
        cout << "Exception - " << w << endl;
    }
    try
    {
        ip4->printIP();
    }
    catch (string w)
    {
        cout << "Exception - " << w << endl;
    }

    system("pause");
    return 0;
}

Pozostało 580 znaków

2019-06-10 16:34
1

W printIP() w pętli while brak wyjścia z pętli. Przez to funkcja zawsze rzuca wyjątkiem.
Zmieniasz tam też wartość scope więc wywołanie ponownie printIP() (na tym samym obiekcie) będzie problemem.
Debugger bardzo pomaga w podobnych sytuacjach. Użyj go.

edytowany 2x, ostatnio: Delor, 2019-06-10 16:38
Nie rozumiem trochę... przecież pętla while powtarza się do momentu kiedy powOfTwo>scope wtedy metoda printIP() przechodzi do warunku if(scope < powOfTwo) gdzie wyjątek zostaje rzucony tylko raz na wybranym obiekcie czyli na ip3 i na ip4. Czyli w pętli while jest wyjście z pętli... Dobrze to rozumiem? - Danielos12 2019-06-10 20:52
W pętli nie wychodzisz (break/return) więc krąży w środku, aż przestanie spełniać warunek scope >= powOfTwo. Wtedy wychodzi i automatycznie spełnia warunek scope < powOfTwo. Dla wszystkich IP. - Delor 2019-06-10 20:57
Ale przecież funkcja ta nie rzuca za każdym razem wyjątkiem. Tylko wtedy gdy ip albo scope nie jest potega liczby 2. A pętla while musi krążyć aż przestanie spełniać warunek scope >= powOfTwo bo inaczej nie sprawdzi poprawnosci danych. Więc gdzie tu jest błąd? - Danielos12 2019-06-10 21:13
Użyj debuggera. Zauważysz, że wyjątek jest rzucany zawsze. - Delor 2019-06-10 21:16

Pozostało 580 znaków

2019-06-10 16:45
1

Istnieje sprytny sposób na sprawdzenie czy liczba jest potęgą dwójki

bool isPowerOfTwo(unsigned value)
{
  return (value && !(value & (value - 1)));
}

Pozostało 580 znaków

2019-06-10 17:00
0

Zakładasz. że każdy element w adresie będzie miał dokładnie 3 cyfry ?

    int getPieceIP(){
        string pieceIp = ip.substr(12, 3);

Nie byłoby wygodniej użyć funkcji typu inet_pton(...) ?

https://stackoverflow.com/que[...]-to-ip-address-and-vice-versa

inet_pton jest powolne bo robi jakieś dodatkowe rzeczy po sieci. - MarekR22 2019-06-10 17:22
Hmm ? Z manuala to raczej nie wynika... - Bartłomiej Golenko 2019-06-10 19:18
to jest zadanie z laborek, więc założyłem że każdy element będzie miał 3 cyfry. Tylko ten wyjątek nie chce mi działać... - Danielos12 2019-06-10 19:59
Wyjątek działa. :) Problem w tym, że za często. - Delor 2019-06-10 20:07
tak wiem, że dokumentacja nic o tym nie mówi. Tak się złożyło, że akurat tydzień temu, mój teammate robił profilowanie i tam mu wyszło wąskie gardło (ku naszemu zdziwieniu). - MarekR22 2019-06-10 21:59
Ciekawe. strace nic dziwnego mi nie pokazywał - ale też nie mierzyłem. Warto zapamiętać. - Bartłomiej Golenko 2019-06-10 22:22

Pozostało 580 znaków

2019-06-10 17:18
1

Sam rzucasz ten wyjątek z:

        if (scope < powOfTwo) {
            string wyjatek = "invalid range";
            throw wyjatek;
        }

https://wandbox.org/permlink/0fJQh6FrAeV66NzY

Może napisz co ten paragram ma robić, bo to ewidentnie jest problem XY


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 3x, ostatnio: MarekR22, 2019-06-10 17:24
scope właśnie odpowiada za to ile razy ip zostanie wyświetlone w konsoli. Aby sprawdzić czy jest potęgą liczby 2, to przechodzi do petli while i poteguje scope tak długo dopóki powOfTwo == scope. Jeśli tak się nie stanie to wtedy scope < powOfTwo, czyli nastepuje wyjście z pętli i przejście do instrukcji scope < powOfTwo którą przedstawiłeś powyżej. Wtedy powinien być rzucony wyjątek który nie działa. - Danielos12 2019-06-10 18:42

Pozostało 580 znaków

2019-06-10 18:29
0

Sory zapomniałem pokazać w jaki sposób program ma działać. Tutaj jak ma wyglądać output. Jest to zwykłe zadanie na laborki:

212.111.212.129

212.111.212.130

212.112.212.129

212.112.212.130

212.112.212.131

212.112.212.132

Exception - invalid range.

Exception - invalid IP number

edytowany 1x, ostatnio: Danielos12, 2019-06-10 18:29
Ale dlaczego ten ostatni adres miałby być nieprawidłowy ? Nie wiem też dlaczego ostatnia wartość miałaby byc koniecznie potęgą 2... - Bartłomiej Golenko 2019-06-10 19:19

Pozostało 580 znaków

2019-06-12 02:01

Dobra naprawiłem. Wystarczyło warunek

if (scope < powOfTwo) {
                string wyjatek = "invalid range";
                throw wyjatek;
            }

umieścić w środku pętli while, a nie na zewnątrz jej

edytowany 4x, ostatnio: Danielos12, 2019-06-12 02:03
fajnie, że pomogłeś sam sobie, ale dam ci dobrą radę. Opisuj swój problem tak jakby druga strona nie miała pojęcia co robisz (bo taka jest prawda). Nawet te dwie ostatnie twoje odpowiedzi zakładają, że wszyscy doskonale wiedzą co ma robić twój program. Dopominaliśmy się o więcej informacji, a ty to zignorowałeś, wiec wątek został zignorowany przez innych (sam skazałeś się na samopomoc). - MarekR22 2019-06-12 11:07
Sory, z pośpiechu źle do tego podszedłem. Na Stacku za takie coś już bym miał minusy... - Danielos12 2019-06-12 11:40
nie masz za co przepraszać. Musisz po prostu nauczyć się dobrze zadawać pytania. Jeśli będziesz pracował w tej branży, to jednym z twoich obowiązków będzie pisanie "bug report", które ma zasady podobne jak na SO lub tutaj (tylko bardziej wymagające, bo dopytywanie się o szczegóły zajmuje czas - czyli pieniądze). A jeszcze bardziej pewne jest to, że znajdziesz się po drugiej stronie, czyli będziesz dostawał "bug" do rozwiązania i wtedy docenisz dobrze opisany problem/wymagania. - MarekR22 2019-06-12 12:20
Rozumiem. Dzięki za rady! - Danielos12 2019-06-12 18:03

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0