Posty

Wyświetlam posty z etykietą CPP

[C++|QT] Zrzut ekranu

Ten wpis jest o tworzeniu zrzutu ekranu za pomocą biblioteki QT. Zacznijmy od utworzenia Qt Widgets Application w Qt Creator. main.cpp #include <QApplication> #include <QScreen> #include <QPixmap> #include <QDateTime> #include <QPushButton> #include <QVBoxLayout> #include <QWidget> #include <QMessageBox> class ScreenshotWidget : public QWidget { Q_OBJECT public: ScreenshotWidget() { // Ustawiamy tytuł okna dla programu setWindowTitle("Zrób zrzut ekranu"); // Tworzymy przycisk QPushButton *button = new QPushButton("Wykonaj zrzut", this); // Ustawiamy układ QVBoxLayout *layout = new QVBoxLayout(this); layout->addWidget(button); setLayout(layout); // Połączenie sygnału kliknięcia przycisku z funkcją takeScreenshot connect(button, &QPushButton::clicked, this, &ScreenshotWidget::takeScreenshot);...

[C++] Program ewidencji studentów

W tym wpisie stworzymy prosty program ewidencji studentów. Program ma mieć następujące możliwości: Wyświetlenie listy studentów; Dodawanie nowego studenta; Usunięcie z listy danego studenta; Jako bazę danych dla listy studentów wykorzystamy plik tekstowy z rozszerzeniem csv. Program ma zapisywać i wyświetlać następujące informacje o studentach: ID, imię i nazwisko, rok urodzenia oraz kierunek studiów. #include <iostream> #include <vector> #include <string> #include <fstream> #include <sstream> class Student { public: int id; // Numer porządkowy studenta std::string name; // Imię std::string surname; // Nazwisko std::string birthDate; // Data urodzenia w formacie d/m/RRRR std::string major; // Kierunek studiów // Konstruktor studenta Student(int id, std::string n, std::string s, std::string bDate, std::string m) : id(id), name(n), surname(s), birthDate(bDate), major(m) {} // Me...

[C++] Tworzenie aplikacji wielowątkowych

Współbieżność jest jednym z kluczowych aspektów programowania wielowątkowego, który pozwala na równoczesne wykonywanie różnych zadań w aplikacji. W języku C++ istnieje wiele narzędzi i mechanizmów, które umożliwiają tworzenie wielowątkowych aplikacji. W tym artykule skupię się na omówieniu kilku popularnych narzędzi współbieżności w C++ oraz przedstawię praktyczny przykład ich użycia. Wątki Język C++ oferuje wbudowane wsparcie dla tworzenia i zarządzania wątkami przy użyciu biblioteki standardowej. Wątki umożliwiają równoczesne wykonywanie różnych fragmentów kodu i mogą być używane do zrównoleglenia obliczeń oraz asynchronicznego wykonania operacji. Mutexy Mutexy są mechanizmem synchronizacji, który zapewnia, że tylko jeden wątek może mieć dostęp do chronionego przez mutex kodu w danym czasie. Dzięki nim można zapewnić bezpieczny dostęp do współdzielonych zasobów i uniknąć wyścigów (race conditions). Zmienne warunkowe Zmienne warunkowe umożliwiają wstrzymywanie wątków i ich wznow...

[C++] Jak obliczyć pole i obwód trapezu?

Przed napisaniem programu obliczającego pole i obwód trapezu, przypomnij sobie wzory. Pole trapezu liczymy według wzoru P=((a+b)*h)/2. Wzór na obwód Ob=a+b+c+d. Obliczając pole trapezu musimy znać rozmiary dwóch podstaw i wysokości. Obliczamy pole trapezu #include <iostream> using namespace std; int main() { int a; int b; int h; double p; cout << "Podaj długość podstawy a: "; cin >> a; cout << "Podaj długość podstawy b: "; cin >> b; cout << "Podaj wysokość: "; cin >> h; if(cin.good() == true) { p = ((a + b) * h) / 2.0; cout << "Pole trapezu wynosi: " << p; } return 0; } Obliczamy obwód trapezu #include <iostream> using namespace std; int main() { int a, b, c, d, ob; cout << "Podaj długość boku a: "; cin >> a; cout << "Podaj długość boku b: "; cin >> b; cout << "Podaj długość boku c: "; cin >> c;...

[C++] Jak sprawdzić ile dni pozostało do danej daty?

Policzenie ile dni pozostało do danej daty może być przydatne w wielu przypadkach. Na przykład, może to być potrzebne do obliczenia czasu pozostałego do ważnego wydarzenia, terminu lub innej istotnej daty. W języku C++ istnieje wiele sposobów, aby to osiągnąć. W tym artykule przedstawię jeden z najprostszych. Biblioteka chrono Biblioteka chrono jest częścią standardowej biblioteki języka C++ i zawiera narzędzia do obsługi czasu i dat. Pozwala na precyzyjne mierzenie czasu, operacje na datach i czasach, a także wykonywanie różnych operacji matematycznych na czasie. Biblioteka ta jest wygodnym narzędziem do zarządzania czasem w aplikacjach C++. Poniższy przykład oblicza ile dni pozostało do danej daty z użyciem właśnie biblioteki chrono. #include <iostream> #include <chrono> #include <ctime> int main() { auto now = std::chrono::system_clock::now(); std::chrono::system_clock::time_point target; std::tm target_time = {}; target_time.tm_year = 2023 -...

[C++] Stos

Zanim przejdziesz do dalszej części wpisu o stosie w C++, zapoznaj się z metodą organizacji i zarządzania danymi LIFO. LIFO czyli Last In, First Out (ostatni wchodzi, pierwszy wychodzi) to metoda organizacji danych, która jest stosowana w niektórych strukturach danych, np. stos. Stos (ang. stack) to struktura danych, która działa właśnie na zasadzie modelu LIFO, co oznacza, że ostatni dodany element jest pierwszym, który zostanie usunięty. Podstawowymi operacjami na stosie są: Push (Dodanie elementu na szczyt stosu); Pop (Usunięcie elementu z góry stosu i zwrócenie go); Top (Zwrócenie elementu z góry stosu bez jego usuwania); Size (Zwraca liczbę elementów w stosie); IsEmpty (Sprawdzenie, czy stos jest pusty); Przykład 1 Prosty przykład programu do zarządzania kolekcją książek: #include <iostream> #include <stack> #include <string> class Book { public: std::string title; Book(const std::string& title) : title(title) {} ...

[C++] Szablony i metaprogramowanie

Programowanie generyczne to jedna z najważniejszych funkcji języka C++. Dzięki szablonom i metaprogramowaniu, programiści mogą pisać bardziej elastyczny i generyczny kod. W tym artykule przyjrzymy się bliżej temu zagadnieniu i przedstawimy, jak wykorzystać te techniki w praktyce. Szablony Szablony w C++ pozwalają na tworzenie generycznych klas i funkcji, które mogą być dostosowane do różnych typów danych. Na przykład, możemy napisać szablon klasy Vector, który może przechowywać elementy dowolnego typu. Dzięki temu, nie musimy pisać oddzielnych implementacji dla różnych typów danych. Przykład template <typename T> class Vector { // Implementacja klasy Vector }; int main() { Vector<int> intVector; Vector<double> doubleVector; // ... return 0; } Kolejnym przykładem może być funkcja sortująca, która może działać zarówno dla typów liczbowych, jak i tekstowych: template <typename T> void sortuj(T tablica[], int rozmiar) { for (int i = 0; i < ro...

[C++] Piszemy aplikację pogodową, część 4

Czwarta część z cyklu Aplikacja pogodowa w C++ . W tym wpisie stworzymy funkcjonalność odpowiadającą za wyświetlanie danych pogodowych w terminalu. W tym celu do obsługi tekstu zostanie użyta biblioteka ncurses . Uwaga! Dla wsparcia polskich znaków konieczne jest użycie ncursesw - nakładki, która wspiera UTF-8. Plik output.hpp Zacznijmy od utworzenia pliku output.hpp i zadeklarowania w nim funkcji display_weather : #ifndef OUTPUT_HPP #define OUTPUT_HPP bool display_weather(char* location); #endif Plik output.cpp Teraz pora na plik output.cpp . Plik ten będzie zawierał najwięcej kodu - logikę funkcji display_weather . Funkcja ta przyjmuje jeden argument - char* location (lokalizacja): #include "data.hpp" #include "output.hpp" #include <ncursesw/ncurses.h> int previous_temperature = 100; int previous_pressure = 0; int previous_humidity = -1; int previous_wind_speed = -1; string temperature_trend = " "; string pressure_trend = " ...

[C++] Piszemy aplikację pogodową, część 3

W części trzeciej tej serii zostanie utworzony kod programu odpowiadający za pobieranie danych pogodowych z serwisu OpenWeather oraz parsowanie pobranego ciągu JSON. Plik data.hpp W pliku data.hpp zadeklarujemy strukturę Weather oraz klasę Data : #ifndef DATA_HPP #define DATA_HPP #include <iostream> using namespace std; struct memory { char *response; size_t size; }; struct Weather { string location; string conditions; int temperature; int pressure; int wind_speed; const char* wind_direction; int humidity; int memory; string error; }; class Data { public: static size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp); public: memory get(string location); Weather set(char* input_location); }; #endif Plik data.cpp W pliku data.cpp tworzymy logikę metod klasy Data . Jak wspomniałem na początku wpisu, kod ten będzie odpowiedzialny za pobieranie danych oraz za parsowanie ciągu JSON. W związku z tym do tego pliku musi...

[C++] Piszemy aplikację pogodową, część 2

W tym wpisie stworzymy kod odpowiadający za konfigurację naszej aplikacji, a będą to pliki config.hpp i config.cpp . Kod ten zawierał będzie deklarację klasy Config z dwiema metodami: create_default_configuration oraz get_option . Pierwsza metoda ma za zadanie stworzyć plik config.cfg z domyślną konfiguracją. Metoda get_option będzie służyła do pobierania danej opcji. Plik config.hpp W tym pliku dołączamy bibliotekę iostream i cstdlib oraz deklarujemy klasę i jej metody. #ifndef CONFIG_HPP #define CONFIG_HPP #include <iostream> #include <cstdlib> using namespace std; class Config { public: void create_default_configuration(); public: string get_option(string option_name); }; #endif Plik config.cpp W tym pliku dołączamy wcześniej utworzony plik nagłówkowy config.hpp , bibliotekę filesystem , bibliotekę fstream oraz tworzymy logikę metod klasy Config . UWAGA! Nie zapomnij w miejsce "ApiKey" wpisać swój API key wygenerowany w panelu OpenWe...

[C++] ncurses Unicode / UTF-8 / polskie znaki

Trafiłeś na ten artykuł, ponieważ zapewne masz problem z polskimi znakami diakrytycznymi przy pracy z biblioteką ncurses . Czy jest na to sposób? Oczywiście, z pomocą przychodzi nakładka ncursesw . Aby zacząć korzystać z ncursesw należy ją najpierw doinstalować. Gdy ncursesw jest już w systemie należy dołączyć do programu nagłówek <ncursesw/ncurses.h> oraz przed zainicjalizowaniem initscr() zainicjować setlocale . Funkcja setlocale powinna zostać zainicjowana z odpowiednim identyfikatorem locale - dla polskich znaków będzie to 'pl_PL.UTF-8'. Instalacja ncursesw Instalacja w: Debian/Ubuntu: apt-get install libncurses5-dev libncursesw5-dev Fedora 21/CentOS: yum install ncurses-devel Fedora 22: dnf install ncurses-devel Przykład użycia ncursesw z UTF-8 #include <clocale> #include <ncursesw/ncurses.h> #include <string.h> int main() { setlocale(LC_ALL, "pl_PL.UTF-8"); int row, col; initscr(); getmaxyx(stdscr,row,col); mvpr...

[C++] Piszemy aplikację pogodową, część 1

Kolejny większy materiał poświęcony programowaniu w C++. Tym razem tematyką tej serii wpisów będzie aplikacja pogodowa . Koncepcja Zadaniem programu będzie pobieranie danych pogodowych dla danej lokalizacji ze zdalnego serwisu. Serwis, który wybrałem jako prowidera danych pogodowych to OpenWeather . Dlaczego akurat Open Weather? Serwis ten ma bardzo intuicyjne API. Do pobierania danych użyta zostanie biblioteka cURL , natomiast format danych, które będzie przetwarzał program to JSON. Bibliotekę do operowania na tych danych wybrałem nlohmann_json . Do obsługi tekstu w terminalu użyta zostanie biblioteka Ncurses Program po uruchomieniu ma sprawdzić czy istnieje plik konfiguracyjny i pobrać z niego ustawienia, a jeśli plik nie istnieje utworzyć go z domyślną konfiguracją. Następnie program ma oczekiwać na podanie przez użytkownika lokalizacji, dla której mają zostać pobrane dane. Po podaniu lokalizacji, program ma wczytać i wyświetlić w terminalu dane takie jak: nazwa lokalizacji , tem...

[C++] Piszemy grę, część 3

W tym wpisie rozbudujemy program o kolejną pętlę do while , w której będzie właściwy kod gry, czyli losowanie liczb, zliczanie prób, liczenie czasu gry itd. Pętla będzie się powtarzała do momentu trafienia poprawnej liczby lub osiągnięcia limitu prób. Do kodu utworzonego w poprzedniej części dopiszmy następujący fragment: do { /* Zależnie od wybranego przez gracza poziomu trudności, ustawiamy limit prób oraz zakres losowania liczby. */ switch(game_level) { // Poziom 1 case 1: attempts_limit = 25; // limit - 25 prób rand_number = rand() % 10 + 1; // losuj liczbę z zakresu 1-10 break; // Poziom 2 case 2: attempts_limit = 15; // limit - 15 prób rand_number = rand() % 50 + 1; // losuj liczbę z zakresu 1-50 break; // Poziom 3 case 3: attempts_limit = 10; // limit - 10 prób rand_number = rand() % 100 + 1; // losuj liczbę z zakresu 1-100 break; } // Z każdą próbą zwięks...

[C++] Jak poznać rozmiar tablicy?

Najprostszą metodą na poznanie rozmiaru (ilości elementów) tablicy w C++ jest użycie operatora sizeof . Operator ten przyjmuje jako argument obiekt lub typ i zwraca rozmiar w bajtach. Operator sizeof #include <iostream> int main() { int cars[] = {1, 2, 3, 4, 5, 6, 7, 8}; int count_cars = sizeof(cars) / sizeof(cars[0]); std::cout << "Ilość cars: " << count_cars << "\n"; std::cout << "Rozmiar cars: " << sizeof cars << "\n"; return 0; } W powyższym przykładzie ilość cars = 8, a rozmiar = 32. Funkcja std::extent Kolejnym sposobem na poznanie rozmiaru tablicy jest użycie funkcji std::extent. Jest to funkcja szablonowa z biblioteki standardowej C++, która pozwala uzyskać liczbę elementów w wymiarze tablicy o określonym indeksie. Funkcja ta jest dostępna od wersji C++ 11. #include <iostream> #include <type_traits> int main() { int cars[5][3][2][9][5]; int rozmiar = std::...

[C++] Usuwanie elementów z kontenera vector

W tym wpisie zajmiemy się modyfikatorem erase kontenera std::vector , dzięki któremu można usunąć jeden lub wiele elementów z kontenera. Metoda erase przyjmuje 3 argumenty: ( iterator ) pos - iterator na element do usunięcia; ( iterator ) first - iterator na pierwszy element z zakresu; ( iterator ) last - iterator na ostatni element z zakresu; Metoda ta zwraca iterator za ostatni usunięty element. Jeśli argument pos wskazuje na ostatni element, metoda erase zwróci element końcowy. Przykład #include <iostream> #include <vector> int main() { std::vector<int> my_vector {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; auto it = my_vector.begin(); my_vector.erase(my_vector.begin() + 4, my_vector.begin() + 9); for(auto &i : my_vector) { std::cout << i << ", "; } return 0; } W powyższym przykładzie z my_vector zostaną usunięte elementy: 5, 6, 7, 8 i 9.

[C++] Piszemy grę, część 2

W poprzednim poście opisałem działanie gry, którą piszemy. W tym zaczniemy pisać właściwy program i już na wstępie zaczniemy od zdefiniowania pliku nagłówkowego history.hpp, który w dalszej części uzupełnimy właściwym kodem. Tworzymy plik history.hpp i definiujemy: #ifndef HISTORY_HPP #define HISTORY_HPP Na razie to tyle jeśli chodzi o plik history.hpp. Teraz zajmiemy się głównym plikiem gry z funkcją main(). Plik ten nazwijmy po prostu gra.cpp i już na początku dołączmy pliki nagłówkowe, w tym nasz plik history.cpp: #include <cstdlib> #include <sstream> #include "history.hpp" cstdlib ze standardowej biblioteki C++ pozwoli nam korzystać z funkcji rand , której użyjemy do losowania liczb z danego przedziału. Definiujemy funkcję main i pierwsze zmienne oraz pierwszą pętlę (do while): int main() { int game_level = 0; // Poziom gry int rand_number = 0; // Wylosowana liczba int attempts = 0; // Liczba prób int attempts_limit = 0; // Limit prób int shot ...

[C++] Piszemy grę, część 1

Postanowiłem kilka przyszłych postów poświęcić językowi C++. Chciałbym pokazać jak w praktyce korzystać z podstawowych elementów C++ takich jak funkcje, instrukcje warunkowe i pętlę. Najlepszym sposobem na naukę jest praktyka, więc napiszemy sobie prosty program, a konkretniej - tekstową grę. Koncepcja Program ma losować liczby całkowite z podanego przedziału, a gracz musi zgadnąć jaka to liczba. Czyli taka zgadywanka liczbowa. Gra ma mieć 3 poziomy trudności: 1 poziom (losowana liczba z przedziału 1 - 10), 2 poziom (losowana liczba z przedziału 1 - 50), 3 poziom (losowana liczba z przedziału 1 - 100). Ponadto każdy poziom ma mieć ograniczoną ilość prób: 1 poziom - 25 prób; 2 poziom - 15 prób; 3 poziom - 10 prób; Czyli im wyższy poziom tym mniej możliwych prób. Tu właściwie kończy się cała filozofia programu. Poniżej opiszę dodatkowe funkcjonalności, które ma mieć program. Start programu i wybór poziomu Na starcie program ma wyświetlić: #--------------------# # Nazwa programu...

[CPP|WMI] Pierwszy program

W tym wpisie stworzymy pierwszy prosty program w C++ z użyciem biblioteki WMI. #include <iostream> #include <comdef.h> #include <Wbemidl.h> #pragma comment(lib, "wbemuuid.lib") int main() { HRESULT hres; // Inicjalizacja COM hres = CoInitializeEx(0, COINIT_MULTITHREADED); if(FAILED(hres)) { std::cout << "Nie można zainicjalizować COM!" << std::endl; return 1; } // Utworzenie sesji WMI IWbemLocator* pLoc = 0; hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc); if(FAILED(hres)) { std::cout << "Nie można utworzyć sesji WMI!" << std::endl; CoUninitialize(); return 1; } // Połączenie z lokalnym przestrzenią nazw WMI IWbemServices* pSvc = 0; hres = pLoc->ConnectServer(_bstr_t(L"ROOT\CIMV2"), ...

[C++] Refleksja w C++, czyli analiza i modyfikacja programu w czasie wykonania

Wprowadzenie Język C++ oferuje wiele zaawansowanych funkcji, które pozwalają programistom na tworzenie wydajnych i elastycznych aplikacji. Jednym z tych zaawansowanych zagadnień jest refleksja, która umożliwia programowi analizę i modyfikację swojej własnej struktury i zachowania w czasie wykonania. W tym artykule przyjrzymy się bliżej temu zagadnieniu i dowiemy się, jak można wykorzystać refleksję w C++. Czym jest refleksja? Refleksja jest zdolnością programu do analizy i modyfikacji swojej własnej struktury i zachowania w czasie wykonania. Dzięki refleksji program może dynamicznie sprawdzać informacje o klasach, metodach, polach i innych składnikach swojego kodu, a także zmieniać ich zachowanie w trakcie działania programu. Mechanizmy refleksji w C++ W języku C++ refleksja jest dostępna dzięki mechanizmom takim jak RTTI (Run-Time Type Information), introspekcja i funkcje meta-programowania . RTTI umożliwia programowi uzyskiwanie informacji o typach danych w czasie wykonania, ...

[C++] Jak przekonwertować string na float?

W tym wpisie postaram się wytłumaczyć jak przekonwertować tekst zawierający w treści liczbę zmiennoprzecinkową. Do konwersji tekstu na liczbę zmiennoprzecinkową służy funkcja std::stof , która przyjmuje dwa argumenty, w tym jeden wymagany. Jak nie trudno się domyślić, wymaganym argumentem jest tekst do przekonwertowania na float . Kolejny argument to pozycja - wartość, która zostanie ustawiona na pozycję pierwszego znaku w podanym jako pierwszy argument ciągu znaków (domyślnie 0). Uwaga! Ta funkcja nie przekonwertuje ciągu na typ int . Aby przekonwertować string na typ int należy użyć funkcji std::stoi . Przykład #include <iostream> #include <string> int main() { std::string text_1 = "11.1"; std::string text_2 = "5.2"; std::string text_3 = "1,2,3"; std::string text_4 = "4000"; float int_type_1 = std::stof(text_1); float int_type_2 = std::stof(text_2); float int_type_3 = std::stof(text_3); float int_type_4 = std::stof...