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

question-closed Zagnieżdżone pętle - wyświetlanie danych z kontenerów

VPS Starter Arubacloud
0 głosów
309 wizyt
pytanie zadane 20 września 2016 w C i C++ przez plkpiotr Stary wyjadacz (12,420 p.)
zamknięte 21 września 2016 przez plkpiotr

Program służy jako baza danych sieci sklepów z zabawkami, o podanym pliku nagłówkowym. Baza danych jest reprezentowana przez kontener (od zera zaimplementowany) składa się z obiektów Chain, która posiada kontener (wektor/STL) obiektów Shop, a te posiadają kontener (wektor/STL) obiektów Toy - jak niżej:

class Toy {
public:
    string name;
    double price;
    int amount;
    Toy(string name, double price, int amount);
    ~Toy() {}
    friend ostream& operator<<(ostream& out, const Toy& toy);
    friend istream& operator>>(istream& in, Toy& toy);
};

class Shop {
public:
    string address;
    vector<Toy> Toys;
public:
    Shop(string address);
    Shop() {}
    ~Shop() {}
    void addToys();
    void addToysExtended(string name, double price, int amount);
    void deleteToy(string name);
    string getAddress();
    friend ostream& operator<<(ostream& out, const Shop& shop);
    friend istream& operator>>(istream& in, Shop& shop);
};

class Chain {
private:
    string trademark;
    unsigned short amount;
public:
    vector<Shop> Shops;
    Chain(string trademark);
    Chain() {};
    ~Chain() {}
    void addShop();
    void addShopExtended(string address);
    string getTrademark();
    friend ostream& operator<<(ostream& out, const Chain& chain);
    friend istream& operator>>(ostream& in, Chain& chain);
};

void displayMenu();
void pressKey();
void clearScreen();

W funkcji głównej main() mam za zadanie wyświetlić zabawki sklepu z danej sieci. Stale próbuję napisać własny sposób wyświetlenia kolejnych zabawek, jednak algorytm działa poprawie tylko dla pierwszego przelotu tzn. dla pierwszej sieci i pierwszego sklepu, próba wyświetlenia zawartości dalszych sieci->sklepów kończy się fiaskiem, bo nic nie wyświetla. Tak wyglądają moje zapiski:

string trademark;
cout << "Chain's name: ";
cin.ignore(USHRT_MAX, '\n');
getline(cin, trademark);
for (it = database.begin(); it != database.end(); it++) {
	if (trademark == (*it).getTrademark() && (*it).Shops.size() != 0) {
		string address;
		cout << "Address: ";
		getline(cin, address);
		for (unsigned short i = 0; i < (*it).Shops.size(); i++) {
			if (address == (*it).Shops[i].address && (*it).Shops[i].Toys.size() != 0) {
				for (unsigned short j = 0; j < (*it).Shops[i].Toys.size(); j++)
					cout << (*it).Shops[i].Toys[j] << endl;
				break;
			}
			if (address == (*it).Shops[i].address && (*it).Shops[i].Toys.size() == 0)
				cout << "No toys." << endl;
			break;
		}
	}
	if (trademark == (*it).getTrademark() && (*it).Shops.size() == 0) {
		cout << "No shops." << endl;
		break;
	}
}

Oddzielne funkcje wyświetlające sieci lub sieci ze sklepami napisałem w porządku, jednak z wyświetlaniem zabawek mam problem, stąd proszę o pomoc...

komentarz zamknięcia: Użytkownik Criss wyjaśnił co było błędem w komentarzach : )
komentarz 20 września 2016 przez MichuDev Pasjonat (20,300 p.)
edycja 21 września 2016 przez MichuDev
std::vector jest do małych kolekcji, nie do baz danych. std::vector rezerwuje tylko 1 blok pamięci. std::deque rezerwuje kilka bloków.
komentarz 20 września 2016 przez plkpiotr Stary wyjadacz (12,420 p.)

Dziękuję za tę uwagę, bo jest to dopiero mój pierwszy, większy projekt, w którym używam biblioteki STL, jednak takie mam wytyczne w poleceniu bo program pisany jest na zajęcia z informatyki, stąd pojawił się std::vector... 

komentarz 21 września 2016 przez criss Mędrzec (172,590 p.)
Nic tzn. nawet nie wyświetla "No shops." / "No toys." ?
komentarz 21 września 2016 przez plkpiotr Stary wyjadacz (12,420 p.)

Tak, nie wyświetla żadnej linijki, może gdzieś niepotrzebnie jest break i pętlę zrywa...

Mam jeszcze pomysł, na wykonanie tego, tyle, że z użyciem iteratora i funkcją zwracającą dane, jednak odpocznę na 1/2 dni od pisania tego programu, żeby złapać inne myślenie.

komentarz 21 września 2016 przez criss Mędrzec (172,590 p.)

Wygląda w porządku... Powinno działać. A już na pewno nie powinno być sytuacji, że nie wyświetla nic. Ten kod (drugi blok) jest w jakiejś funkcji czy w jaki sposób go wykonujesz drugi raz? Pokaż więcej.

komentarz 21 września 2016 przez plkpiotr Stary wyjadacz (12,420 p.)
Ok, zaraz wrzucę projekt na dysk google :)
Dzięki za zainteresowanie, bo zachodzę w głowę przez kilka godzin co jest nie tak...
1
komentarz 21 września 2016 przez criss Mędrzec (172,590 p.)
Ah, na te break-i nie zwróciłem uwagi. Wyrzuć wszystkie bo są niepotrzebne kompletnie. Szczególnie ten w linii 14. Nie wiem jak to działało...
1
komentarz 21 września 2016 przez criss Mędrzec (172,590 p.)

A te ify w stylu ...

if (address == (*it).Shops[i].address && (*it).Shops[i].Toys.size() == 0)

...wywal za pętle. Bez sensu sprawdzać czy kontener jest pusty co obrót pętli skoro wiadomo, że nie jest jeśli pętla leci.

Sprawdzenia w stylu (*it).Shops[i].Toys.size() != 0 bez potzreby zupełnie. Jeśli w ogóle dotarło do tego ifa, to wiadomo, że nie jest pusty.

I nie wrzucaj na żaden dysk :P wywal te breaki po prostu i reszte co wskazałem

komentarz 21 września 2016 przez plkpiotr Stary wyjadacz (12,420 p.)

Jednak nie wrzucę całego kodu do sieci, bo znaleziono winowajcę ;)
Istotnie po „zakomentowaniu” break'ów zabawki są wyświetlane.

Nie rozumiem dlaczego tak mi na nich zależało, że tyle ich tam wsadziłem o.O
Wielkie dzięki za pomoc, bo tak myślałem, że problem jest błahy, jednak dla mnie niewidoczny, jeżeli mogę się odwdzięczyć - to jeśli jest możliwe przemianuj komentarz z if'ami na odpowiedź, bo zasługuje na najlepszą...

1
komentarz 21 września 2016 przez criss Mędrzec (172,590 p.)
Podobno jakoś się dało.. ale nie mam pojęcia jak. Ważne, że się wyjaśniło :P
komentarz 21 września 2016 przez plkpiotr Stary wyjadacz (12,420 p.)

Dla potomnych :)
Jeżeli ktoś miałby jakieś zastrzeżenia - bardzo proszę...

string trademark;
cout << "Chain's name: ";
cin.ignore(USHRT_MAX, '\n');
getline(cin, trademark);
for (it = database.begin(); it != database.end(); it++) {
	if (trademark == (*it).getTrademark() && (*it).Shops.size() != 0) {
		string address;
		cout << "Address: ";
		getline(cin, address);
		for (unsigned short i = 0; i < (*it).Shops.size(); i++) {
			if (address == (*it).Shops[i].address && (*it).Shops[i].Toys.size() == 0)
				cout << "No toys." << endl;
			else if (address == (*it).Shops[i].address) {
				for (unsigned short j = 0; j < (*it).Shops[i].Toys.size(); j++)
					cout << (*it).Shops[i].Toys[j] << endl;
			} else if (i == (*it).Shops.size() - 1)
				cout << "This shop doesn't exist." << endl;
		}
	} else if (trademark == (*it).getTrademark() && (*it).Shops.size() == 0)
		cout << "No shops." << endl;
	else if (trademark != (*it).getTrademark() && it == database.end() - 1)
		cout << "This chain doesn't exist." << endl;
}

Zastanawiam się jedynie, nad break'ami - czy w odpowiednich miejscach nie przyspieszyłyby one działania programu?

1
komentarz 21 września 2016 przez criss Mędrzec (172,590 p.)

Tutaj:

            if (address == (*it).Shops[i].address && (*it).Shops[i].Toys.size() == 0)
                cout << "No toys." << endl;

i tutaj:

else if (trademark == (*it).getTrademark() && (*it).Shops.size() == 0)
        cout << "No shops." << endl;

Jeśli już w tych momentach jesteś w stanie stwierdzić, że "No toys." / "No shops." to możesz wrzucić w te ify break-a. Nie ma sensu dalej sprawdzać jeśli wiesz, że dalej już nic nie znajdziesz. Tylko wtedy wnioskuje, że w database i w Shops istnieją tylko unikaty - tzn. jest max jeden obiekt (w database) o danym trademarku i max jeden sklep o danym adresie. Jeśli tak nie jest, to nie wiem na jakiej podstawie stwierdzasz, że nie ma sklepów / zabawek jeszcze przed przeszukaniem wszystkiego.

komentarz 21 września 2016 przez plkpiotr Stary wyjadacz (12,420 p.)
Dzięki raz jeszcze :)
Widzę, że nie mam wystarczającej wiedzy/doświadczenia, bo faktycznie tego nie rozpatrzyłem o czym piszesz...
1
komentarz 21 września 2016 przez criss Mędrzec (172,590 p.)
Przyjdzie z czasem :P

Podobne pytania

+1 głos
2 odpowiedzi 916 wizyt
pytanie zadane 22 stycznia 2021 w C i C++ przez Karson Obywatel (1,000 p.)
0 głosów
3 odpowiedzi 991 wizyt
pytanie zadane 2 maja 2020 w Python przez lenzo1 Początkujący (360 p.)
0 głosów
1 odpowiedź 707 wizyt
pytanie zadane 24 czerwca 2019 w C i C++ przez magda_19 Gaduła (3,080 p.)

92,451 zapytań

141,261 odpowiedzi

319,073 komentarzy

61,853 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

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 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!

...