• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Skrócenie kodu z uwagi na switch() w podfunkcjach, które różną się warunkiem if()

Object Storage Arubacloud
0 głosów
320 wizyt
pytanie zadane 29 sierpnia 2016 w C i C++ przez plkpiotr Stary wyjadacz (12,420 p.)
edycja 29 sierpnia 2016 przez plkpiotr
// Rodzaj to typ wyliczeniowy enum
// Nagłówku funkcji nie mogę zmienić, bo taki mam w poleceniu
void Tekst::pobierzPlik(bool flaga, Rodzaj przyznany, ifstream& wejscie)
{
    char litera;
    unsigned short licznik = 0;
    switch(przyznany)
    {
    case alfabetyczne :
        while(!wejscie.eof())
        {
            wejscie.get(litera);
            if(isalpha(litera) && licznik<ROZMIAR)
            {
                znaki[licznik]=litera;
                licznik++;
            }
        }
        znaki[licznik]='\0';
        break;
    case alfanumeryczne :
        while(!wejscie.eof())
        {
            wejscie.get(litera);
            if(isalnum(litera) && licznik<ROZMIAR)
            {
                znaki[licznik]=litera;
                licznik++;
            }
        }
        znaki[licznik]='\0';
        break;
    case bezBialychZnakow:
        while(!wejscie.eof())
        {
            wejscie.get(litera);
            if(!isspace(litera) && licznik<ROZMIAR)
            {
                znaki[licznik]=litera;
                licznik++;
            }
        }
        znaki[licznik]='\0';
        break;
    case bezNowychWierszy:
        while(!wejscie.eof())
        {
            wejscie.get(litera);
            if(litera!='\n' && licznik<ROZMIAR)
            {
                znaki[licznik]=litera;
                licznik++;
            }
        }
        znaki[licznik]='\0';
        break;
    }
}

Chciałbym skrócić powyższy kod. Jest to funkcja, która ma odczytywać odpowiednie znaki z pliku (litery alfabetu, znaki alfanumeryczne, znaki z pominięciem białych albo znaki z pominięciem nowego wiersza). Jak widać cztery "podfunkcje" (wybaczcie za robocze określenie) różnią się wyłącznie podświetlonymi warunkami... Czy można jakoś te warunki przypisać np. zmiennym, by switch mógł decydować o warunku? Zmiennym logicznym nie bardzo, bo te są w stanie przekazać jedynie true lub false... Przydałoby się jakoś wykorzystać w tym wszystkim flagi... Może da się bez switcha? Mógłbym prosić o jakieś pomysły? blush

2 odpowiedzi

+1 głos
odpowiedź 29 sierpnia 2016 przez MetRiko Nałogowiec (37,110 p.)
wybrane 29 sierpnia 2016 przez plkpiotr
 
Najlepsza

To rozwiązanie powinno się nadać:
Nie testowałem tego kodu.. możliwe drobne błędy kompilacji..

bool Sprawdz(Rodzaj Typ, char &Litera)
{
    switch(Typ)
    case alfabetyczne: return isalpha(litera); //Return również kończy działanie funkcji, tak więc break; jest niepotrzebny
    case alfanumeryczne: return isalnum(litera);
    case bezBialychZnakow: return !isspace(litera);
    case bezNowychWierszy: return litera!='n';
    return 0;
}

void Tekst::pobierzPlik(bool flaga, Rodzaj przyznany, ifstream& wejscie)
{
    char litera;
    unsigned short licznik = 0;
    while(!wejscie.eof())
    {
        wejscie.get(litera);
        if(Sprawdz(przyznany,litera) && licznik<ROZMIAR)
        {
            znaki[licznik]=litera;
            licznik++;
        }
    }
    znaki[licznik]='';
}

 

1
komentarz 29 sierpnia 2016 przez plkpiotr Stary wyjadacz (12,420 p.)
Dziękuję bardzo za odpowiedź, po tej nocy napiszę, czy współgra z resztą kodu :) Póki co idę spać ;)
1
komentarz 29 sierpnia 2016 przez plkpiotr Stary wyjadacz (12,420 p.)

Kapitalne! Bazując na obecnej wiedzy nie wpadłbym za nic na takie rozwiązanie, stąd bardzo jestem wdzięczny za pomoc. :)

Działa chyba lepiej niż myślałem ;)

Tak wygląda wersja z koniecznymi, ale kosmetycznymi zmianami:

// Wersja MetRiko

bool okreslFlage(Rodzaj Typ, char &litera) {
	switch (Typ) {
	case alfabetyczne:
		return isalpha(litera);
	case alfanumeryczne:
		return isalnum(litera);
	case bezBialychZnakow:
		return !isspace(litera);
	case bezNowychWierszy:
		return litera != '\n';
	}
	return 0;
}

void Tekst::pobierzPlik(bool flaga, Rodzaj przyznany, ifstream& wejscie) {
	char litera;
	unsigned short licznik = 0;
	while (!wejscie.eof()) {
		wejscie.get(litera);
		if (okreslFlage(przyznany, litera) && licznik < ROZMIAR) {
			znaki[licznik] = litera;
			licznik++;
		}
	}
	znaki[licznik] = '\0';
}

 

+1 głos
odpowiedź 29 sierpnia 2016 przez Magicone Nałogowiec (45,100 p.)
A nie lepiej odwrócić zależności i wykonać odpowiednią metodę do klasy Rodzaj z przekazaniem danych, w niej wykonywać odpowiednie akcje?
komentarz 29 sierpnia 2016 przez plkpiotr Stary wyjadacz (12,420 p.)
To znaczy dopisać dodatkowe, oddzielne cztery metody?
1
komentarz 29 sierpnia 2016 przez Magicone Nałogowiec (45,100 p.)
Nie, podzielić klasy ze względu na to, jakie działania powinny podejmować w tym konkretnym wypadku.
komentarz 29 sierpnia 2016 przez plkpiotr Stary wyjadacz (12,420 p.)
edycja 29 sierpnia 2016 przez plkpiotr
Rozwiązanie jak najbardziej trafne, za nie również dziękuję, jak i za pomoc w szerszym spojrzeniu na problem, jednak wytyczne w zadaniu, którego polecenia nie przytoczyłem zakładają wyłącznie jedną klasę...

Podobne pytania

0 głosów
3 odpowiedzi 1,081 wizyt
0 głosów
1 odpowiedź 269 wizyt
pytanie zadane 16 kwietnia 2022 w Python przez niezalogowany
0 głosów
0 odpowiedzi 176 wizyt
pytanie zadane 6 listopada 2016 w JavaScript przez blackvten Nowicjusz (180 p.)

92,555 zapytań

141,404 odpowiedzi

319,557 komentarzy

61,940 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...