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

Różne odczyty z niezmiennej tablicy z pliku .h

Object Storage Arubacloud
0 głosów
198 wizyt
pytanie zadane 6 listopada 2022 w C i C++ przez Krzysztofs1234 Użytkownik (890 p.)

Dzień dobry,

obecny problem wynikł z problemu opisanego tutaj: https://forum.pasja-informatyki.pl/574030/dziedziczony-singleton-dostepny-tylko-dla-klas

W skrócie:

Robiąc zadanie z odc. 3 z OOP w C++ od p. Zelenta, chciałem móc podstawić nazwę miesiąca za nr miesiąca i i wyliczyć jaki dzień tygodnia będzie w danej dacie. Potrzebowałem czegoś, co przechowa nazwy słowne dni tygodnia oraz miesięcy i spełnia następujące kryteria:

- jest niezmienne w swej postaci

- nie ma żadnych kopii, jest co najwyżej jeden egzemplarz danych

- jest dostępne dla wybranych klas

- służy tylko do odczytu

Po rozmowach doszedłem do wniosku, że najlepsza będzie funkcja zaprzyjaźniona przechowująca pola będące tablicami pożądanych wartości. Niestety, mając jedną klasę w jednym pliku i drugą klasę zaprzyjaźnioną w drugim i załączając je wzajemnie za pomocą include, dochodziło do błędów.

Zdecydowałem się stworzyć plik nagłówkowy ze stałymi tablicami - MonthsAndDays,h i załączyłem ją tylko do pliku Event.cpp. W końcu osiągnąłem 4/4 punkty.

To, co jednak dzieje się w głównej funkcji, jest nie do przyjęcia. Korzystając z funkcji show() dla obiektu event1 z domyślnymi parametrami, mam poprawne dane - sobota. Nadpisując te parametry funkcją load() i dając te same wartości, mam inny dzień - poniedziałek. A próba wyświetlenia dwóch zainicjalizowanych obiektów jeden po drugim powoduje błąd programu. Próbowałem to zrobić z opóźnieniem (Sleep), bo może dostęp do tych komórek nie był zwolniony (?), ale nie pomagało.

 

Proszę o pomoc.

 

main.cpp

#include "Event.h"

#include <iostream>
#include <windows.h>
using namespace std;

int main()
{
    Event event1, event2;

    event1.show();
    //Sleep(10000);
    //event2.show();

    cout << endl;
    event1.load();

    cout << endl;
    event1.show();

    return 0;
}

 

Event.h

#ifndef EVENT_H
#define EVENT_H

#include "Event.h"

#include <iostream>


class Event
{
private:
    std::string name;
    std::string place;
    unsigned short day, month, year;
    unsigned short hour, minutes;

    unsigned short weeks_day;


public:
    Event(std::string="nazwa", std::string="miejsce", unsigned short=1, unsigned short=1,
          unsigned short=2000, unsigned short=0, unsigned short=0);
    ~Event();

    void load();
    void show() const;

private:
    void Zellers_congruity();
    unsigned short Zellers_month() const;
    unsigned short Zellers_century() const;
    unsigned short Zellers_century_year() const;

};

#endif // EVENT_H

 

Event,cpp

#include "Event.h"
#include "MonthsAndDays.h"

using namespace std;


Event::Event(string name, string place, unsigned short day, unsigned short month, unsigned short year, unsigned short hour, unsigned short minutes)
{
    this->name=name;
    this->place=place;
    this->day=day;
    this->month=month;
    this->year=year;
    this->hour=hour;
    this->minutes=minutes;
}


Event::~Event()
{
    cout << endl << "Usuwanie obiektu." << endl;
}


void Event::load()
{
    cout << "KREATOR WYDARZEN" << endl << endl;

    cout << "Nazwa: ";
    getline(cin, name);

    cout << "Miejsce: ";
    getline(cin, place);

    cout << "Dzien miesiaca: ";
    cin >> day;

    cout << "Numer miesiaca: ";
    cin >> month;

    cout << "Rok: ";
    cin >> year;

    cout << "Godzina (sama godzina): ";
    cin >> hour;

    cout << "Minuty: ";
    cin >> minutes;

    Zellers_congruity();
 }


void Event::show() const
{
    cout << "Wydarzenie '" << name << "' odbedzie sie w miejscu '" << place << "' " << day << " " << monthToText[month] << " ";
    cout << year << " roku" << " (" << dayOfWeekToText[weeks_day] << ") " << "o godzinie " << hour << ":" << minutes << "." << endl;
}

void Event::Zellers_congruity()
{
    unsigned short J{Zellers_century()}, K{Zellers_century_year()};
    weeks_day=(day + 13*(Zellers_month()+1)/5 + J/4 + 5*J + K + K/4)%7;
}


unsigned short Event::Zellers_month() const
{
    if(month<3) return month+12;
    return month;
}


unsigned short Event::Zellers_century() const
{
    return year/100;
}


unsigned short Event::Zellers_century_year() const
{
    return year%100;
}

 

MonthsAndDays.h

#ifndef MonthsAndDays_H
#define MonthsAndDays_H

#include <iostream>


const std::string monthToText[]
{
    "",
    "stycznia",
    "lutego",
    "marca",
    "kwietnia",
    "maja",
    "czerwca",
    "lipca",
    "sierpnia",
    "wrzesnia",
    "pazdziernika",
    "listopada",
    "grudnia"
};

const std::string dayOfWeekToText[]
{
    "sobota",
    "niedziela",
    "poniedzialek",
    "wtorek",
    "sroda",
    "czwartek",
    "piatek"
};

#endif // MonthsAndDays_H

 

1 odpowiedź

+1 głos
odpowiedź 6 listopada 2022 przez tangarr Mędrzec (154,860 p.)
wybrane 6 listopada 2022 przez Krzysztofs1234
 
Najlepsza
Zmienna weeks_day nie jest inicjalizowana w konstruktorze. Dlatego funkcja show wywołana zaraz po stworzeniu obiektu może wysypać program.
komentarz 6 listopada 2022 przez j23 Mędrzec (194,920 p.)

Dodam, że na końcu load wywołujesz Zellers_congruity, to samo powinieneś zrobić w konstruktorze.

komentarz 6 listopada 2022 przez Krzysztofs1234 Użytkownik (890 p.)
Tak, właśnie to mi wpadło do głowy, że mogę dać tę funkcję w ciele konstruktora, na końcu.

Dziękuję.
komentarz 6 listopada 2022 przez Krzysztofs1234 Użytkownik (890 p.)

Teraz zepsuła mi się albo taka była kongruencja Zellera. https://swistak.codes/post/okreslanie-dnia-tygodnia-dla-dowolnej-daty/

Zdaje się dobrze działać dla miesięcy od marca i dalej, ale styczeń i luty już nie, wnioskując po moich próbach. Patrzę i patrzę, i nie wiem, co tym razem. :/

#include "Event.h"
#include "MonthsAndDays.h"

using namespace std;


Event::Event(string name, string place, unsigned short day, unsigned short month, unsigned short year, unsigned short hour, unsigned short minutes)
{
    this->name=name;
    this->place=place;
    this->day=day;
    this->month=month;
    this->year=year;
    this->hour=hour;
    this->minutes=minutes;

    Zellers_congruity();
}


Event::~Event()
{
    cout << endl << "Usuwanie obiektu." << endl;
}


void Event::load()
{
    cout << "KREATOR WYDARZEN" << endl << endl;
    fflush(stdin);

    cout << "Nazwa: ";
    getline(cin, name);

    cout << "Miejsce: ";
    getline(cin, place);

    cout << "Dzien miesiaca: ";
    cin >> day;

    cout << "Numer miesiaca: ";
    cin >> month;

    cout << "Rok: ";
    cin >> year;

    cout << "Godzina (sama godzina): ";
    cin >> hour;

    cout << "Minuty: ";
    cin >> minutes;

    Zellers_congruity();
 }


void Event::show() const
{
    cout << "Wydarzenie '" << name << "' odbedzie sie w miejscu '" << place << "' " << day << " " << monthToText[month] << " ";
    cout << year << " roku" << " (" << dayOfWeekToText[weeks_day] << ") " << "o godzinie " << hour << ":" << minutes << "." << endl;
}

void Event::Zellers_congruity()
{
    unsigned short J{Zellers_century()}, K{Zellers_century_year()};
    weeks_day=(day + 13*(Zellers_month()+1)/5 + J/4 + 5*J + K + K/4)%7;
}


unsigned short Event::Zellers_month() const
{
    if(month<3)
    {
        cout << "m=" << month+12 << endl;
        return month+12;
    }
    cout << "m=" << month << endl;
    return month;
}


unsigned short Event::Zellers_century() const
{
    cout << "J=" << year/100 << endl;
    return year/100;
}


unsigned short Event::Zellers_century_year() const
{
    cout << "K=" << year%100 << endl;
    return year%100;
}

Czy byłby ktoś uprzejmy mi pomóc?

1
komentarz 6 listopada 2022 przez j23 Mędrzec (194,920 p.)
Jeśli miesiącem jest styczeń lub luty, powinieneś odjąć jeden rok przy obliczaniu dnia tygodnia.
1
komentarz 6 listopada 2022 przez Krzysztofs1234 Użytkownik (890 p.)
I znów celna uwaga. Dzięki.

Podobne pytania

0 głosów
1 odpowiedź 334 wizyt
pytanie zadane 5 sierpnia 2018 w Sprzęt komputerowy przez Loki Użytkownik (560 p.)
0 głosów
1 odpowiedź 512 wizyt
0 głosów
1 odpowiedź 95 wizyt

92,702 zapytań

141,616 odpowiedzi

320,180 komentarzy

62,062 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

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!

...