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

Przenoszenie obiektu z jednego pliku do drugiego

+1 głos
117 wizyt
pytanie zadane 3 kwietnia 2021 w C i C++ przez DzikieHarce Użytkownik (510 p.)
Staram się napisać bazę danych w c++, dla biblioteki. Chcę napisać funkcję która będzie przepisywała jedną osobę z pliku Wolny.txt do pliku Dluznik.txt. Chodzi o obsługę wypożyczeń. Program pyta o id osoby która chce wypożyczyć książkę, potem przepisuje tą osobę z jednego pliku do drugiego, ale zostawia w poprzednim całą resztę. W programie są dwie klasy Wolny i Dluznik dziedziczące po klasie Osoby. Wszystkie klasy mają trzy zmienne, zapisanie w tej kolejności: nazwisko, imię, id. Moim pomysłem jest włożyć wszystkie osoby z pliku Wolny.txt do listy, a do drugiej dać tylko tę osobę która ma odpowiednie id. Potem ponownie zapisać do pliku Wolny.txt wszystkie dane z pierwszej listy, a z drugiej dopisać jedynie tę jedną osobę. Ewentualnie wczytać wszystko z pliku Wolny.txt do listy, potem ją przeszukać i ew. przepisać do innej, jeśli znajdzie się id o właściwym numerze, a potem usunąć z pierwszej listy tylko ten jeden obiekt. Nie mam jednak pojęcia jak zabrać się do pisania tych funkcji.
1
komentarz 4 kwietnia 2021 przez tkz Nałogowiec (41,900 p.)
std::optional<user> findById(long id, const std::unordered_map<long, user> &users)
{
    if (auto findUser = users.find(id); findUser != users.end())
        return findUser->second;
    return std::nullopt;
}

int main()
{
    {
        auto user = findById(5, users);
        std::cout << "optional-------------\n";
        if (user)
        {
            std::cout << user.value().name << '\n';
            std::cout << user.value().surname << '\n';
        }
        std::cout << "optional-------------\n";
        user = findById(1001, users);
        if (user)
        {
            std::cout << user.value().name << '\n';
            std::cout << user.value().surname << '\n';
        }
    }
}

Można też tak, w mojej opinii bardziej zgodnie ze sztuką. 
Co do linków: https://en.cppreference.com/w/cpp/utility/optional/operator_bool dlaczego if(user) - może wydawać się dziwne na początku. 
I sam optional https://en.cppreference.com/w/cpp/utility/optional

komentarz 4 kwietnia 2021 przez DzikieHarce Użytkownik (510 p.)

Chyba rozumiem ;D Na razie udało mi się na listach, teraz biorę się za mapy, warto przećwiczyć obie opcje. Bardzo mi się przydała twoja pomoc, dozgonna wdzięczność ^^ A jeśli ktoś by był ciekawy, tutaj mój kod z listami:

void przepisz(int idSzuk)
{
	list<string> listaW;
	list<string> listaD;
	ifstream plikW;
	fstream plikD;
	string linia;
	string imie, nazwisko, id;
	plikW.open("Wolny.txt");
	plikD.open("Dluznik.txt", ios::out | ios::app);
	int nrOsoby = 1;
	int nrLinii;
	int i = 1, szuk;
	int licznik = 1;
	while (plikW>>nazwisko>>imie>>szuk)
	{
			if (szuk == idSzuk)
			{
				id = to_string(szuk);
				listaD.push_back(nazwisko);
				listaD.push_back(imie);
				listaD.push_back(id);
			}
			else
			{
				id = to_string(szuk);
				listaW.push_back(nazwisko);
				listaW.push_back(imie);
				listaW.push_back(id);
			}
			//}
			licznik++;
	}
		plikW.close();
		//Wpisywanie do plików
		ofstream plikW2;
		plikW2.open("Wolny.txt");
		string zmienna;
		for (list<string>::iterator it = listaW.begin(); it != listaW.end(); it++)
		{
			zmienna = *it;
			plikW2 <<endl << zmienna;
			plikW2.flush();
		}
		for (list<string>::iterator it = listaD.begin(); it != listaD.end(); it++)
		{
			zmienna = *it;
			plikD << endl << zmienna;
			plikD.flush();
		}
		plikW.close();
		plikD.close();
}

Pomysł z while(plikW>>nazwisko>>imie>>id) o wiele lepszy, nie wiem czemu na to nie wpadłam wcześniej.

1
komentarz 4 kwietnia 2021 przez tkz Nałogowiec (41,900 p.)
void przepisz(int idSzuk)
{
    using namespace std;
    list<string> listaW;
    list<string> listaD;
    fstream plikW("Wolny.txt", ios::in | ios::out /*| ios::app o ile chcesz*/);
    fstream plikD("Dluznik.txt", ios::out | ios::app);
    int szuk;
    string imie, nazwisko;
    while (plikW >> nazwisko >> imie >> szuk)
    {
        if (szuk == idSzuk)
        {
            listaD.push_back(nazwisko);
            listaD.push_back(imie);
            listaD.push_back(to_string(szuk));
        }
        else
        {
            listaW.push_back(nazwisko);
            listaW.push_back(imie);
            listaW.push_back(to_string(szuk););
        }
    }
    for (const auto &i : listaW)
    {
        plikW << endl
              << i;
    }
    for (const auto &i : listaD)
    {
        plikD << endl
              << i;
    }
}

Nieco uproszczone, nie wiem, czy się kompiluje, nie miałem jak sprawdzić. 

komentarz 4 kwietnia 2021 przez DzikieHarce Użytkownik (510 p.)
Twoje wygląda znacznie lepiej, nie rozumiem tylko jak działają te pętle for. Pobierają osobno dane z listy? To czemu tam jest auto, skoro w liście są tylko stringi?
1
komentarz 4 kwietnia 2021 przez tkz Nałogowiec (41,900 p.)
Słówko auto "domyśla" się typu, nie muszę pisać go ręcznie. Co do pętli: https://en.cppreference.com/w/cpp/language/range-for i https://www.geeksforgeeks.org/range-based-loop-c/ drugi link jest przystępniejszy.
https://cppinsights.io/ wrzuć gotowy kod, pokaże dokładne rozbicie pętli range for.

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

0 głosów
2 odpowiedzi 121 wizyt
0 głosów
2 odpowiedzi 137 wizyt
0 głosów
0 odpowiedzi 326 wizyt

88,355 zapytań

136,951 odpowiedzi

305,666 komentarzy

58,618 pasjonatów

Motyw:

Akcja Pajacyk

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

Sklep oferujący ćwiczenia JavaScript, PHP, rozmowy rekrutacyjne dla programistów i inne materiały

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...