Operacje na plikach tekstowych

Kurs: Wstęp do programowania
Lekcja 5: Obsługa plików i pamięci
Temat 2: Operacje na plikach tekstowych

⇓ spis treści ⇓


Pliki tekstowe są jednym z najczęściej używanych formatów do przechowywania danych w programowaniu. Zrozumienie, jak otwierać, odczytywać, zapisywać i zamykać pliki tekstowe, jest kluczowe dla tworzenia programów, które mogą przechowywać informacje trwałe, wymieniać dane lub wczytywać konfiguracje. W tej lekcji omówimy szczegółowo wszystkie niezbędne operacje na plikach tekstowych w języku C++, w tym sposoby radzenia sobie z błędami i najlepsze praktyki w zakresie manipulacji plikami.

Podstawy pracy z plikami tekstowymi

W C++ do pracy z plikami tekstowymi wykorzystujemy bibliotekę fstream, która udostępnia klasy ifstream do odczytu z plików, ofstream do zapisu do plików oraz fstream do operacji wejścia/wyjścia na plikach. Przed przystąpieniem do odczytu lub zapisu danych musimy najpierw otworzyć plik, a po zakończeniu pracy z plikiem należy go zamknąć, aby zwolnić zasoby systemowe.

Otwarcie pliku

Aby otworzyć plik tekstowy, należy utworzyć obiekt jednej z klas fstream i wywołać metodę open(). Możemy również otworzyć plik bezpośrednio w momencie tworzenia obiektu, podając nazwę pliku jako argument w konstruktorze. Oto przykłady:

Przykład otwierania pliku do odczytu
#include <fstream>
#include <iostream>

int main() {
    std::ifstream plik("dane.txt"); // Otwieranie pliku do odczytu
    if (!plik.is_open()) {
        std::cerr << "Nie można otworzyć pliku!" << std::endl;
        return 1;
    }
    // Operacje na pliku
    plik.close(); // Zamknięcie pliku
    return 0;
}

W powyższym przykładzie używamy klasy ifstream do otwarcia pliku dane.txt w trybie odczytu. Sprawdzamy, czy plik został poprawnie otwarty, używając metody is_open(). Jeśli plik nie został otwarty, wyświetlamy komunikat o błędzie i kończymy działanie programu.

Przykład otwierania pliku do zapisu
#include <fstream>
#include <iostream>

int main() {
    std::ofstream plik("wyniki.txt"); // Otwieranie pliku do zapisu
    if (!plik) {
        std::cerr << "Nie można otworzyć pliku do zapisu!" << std::endl;
        return 1;
    }
    // Operacje na pliku
    plik.close(); // Zamknięcie pliku
    return 0;
}

W przypadku zapisu do pliku używamy klasy ofstream. Jeśli plik nie istnieje, zostanie utworzony. Jeśli istnieje, jego zawartość zostanie nadpisana. Dlatego warto być ostrożnym podczas otwierania plików w trybie zapisu.

Tryby otwierania plików

Podczas otwierania pliku możemy określić różne tryby pracy, które kontrolują sposób, w jaki plik jest używany. Oto najczęściej używane tryby:

  • std::ios::in: Otwiera plik w trybie odczytu.
  • std::ios::out: Otwiera plik w trybie zapisu. Zawartość pliku zostanie nadpisana.
  • std::ios::app: Otwiera plik w trybie dopisywania. Dane są dodawane na końcu pliku.
  • std::ios::binary: Otwiera plik w trybie binarnym, co jest używane do pracy z plikami binarnymi, a nie tekstowymi.
  • std::ios::ate: Otwiera plik i ustawia wskaźnik na jego końcu.
  • std::ios::trunc: Otwiera plik i usuwa jego zawartość, jeśli istnieje.

Możemy łączyć tryby, używając operatora |. Na przykład, aby otworzyć plik w trybie zapisu i dopisywania, możemy użyć std::ios::out | std::ios::app.

Odczyt danych z pliku tekstowego

Do odczytu danych z pliku tekstowego możemy użyć różnych metod, takich jak getline(), operator >> lub metody read() dla bardziej zaawansowanych operacji. Każda z tych metod ma swoje zastosowania w zależności od tego, jakiego rodzaju danych oczekujemy.

Przykład odczytu linii tekstu
#include <fstream>
#include <iostream>
#include <string>

int main() {
    std::ifstream plik("dane.txt");
    if (!plik) {
        std::cerr << "Nie można otworzyć pliku!" << std::endl;
        return 1;
    }

    std::string linia;
    while (std::getline(plik, linia)) {
        std::cout << linia << std::endl; // Wyświetlenie linii tekstu
    }

    plik.close();
    return 0;
}

W powyższym przykładzie używamy funkcji std::getline() do odczytu pliku linia po linii. Jest to przydatne, gdy chcemy odczytać dane w formacie tekstowym.

Przykład odczytu danych słowo po słowie
#include <fstream>
#include <iostream>
#include <string>

int main() {
    std::ifstream plik("dane.txt");
    if (!plik) {
        std::cerr << "Nie można otworzyć pliku!" << std::endl;
        return 1;
    }

    std::string slowo;
    while (plik >> slowo) {
        std::cout << slowo << std::endl; // Wyświetlenie każdego słowa
    }

    plik.close();
    return 0;
}

Operator >> odczytuje dane słowo po słowie, ignorując białe znaki. To wygodny sposób na analizę tekstu, jeśli chcemy przetwarzać dane w formacie słów.

Zapisywanie danych do pliku tekstowego

Zapisywanie danych do pliku tekstowego jest równie proste jak ich odczyt. Używamy klasy ofstream i operatora <<, aby zapisywać dane w formacie tekstowym. Możemy również korzystać z metody write(), aby zapisywać dane w bardziej kontrolowany sposób.

Przykład zapisu danych do pliku
#include <fstream>
#include <iostream>

int main() {
    std::ofstream plik("wyniki.txt");
    if (!plik) {
        std::cerr << "Nie można otworzyć pliku do zapisu!" << std::endl;
        return 1;
    }

    plik << "To jest pierwszy wiersz." << std::endl;
    plik << "To jest drugi wiersz." << std::endl;

    plik.close();
    return 0;
}

W tym przykładzie zapisujemy dwa wiersze tekstu do pliku wyniki.txt. Używamy operatora << oraz std::endl, aby dodać znak nowej linii.

Sprawdzanie i obsługa błędów

Podczas pracy z plikami tekstowymi mogą wystąpić różne błędy, takie jak brak dostępu do pliku, błędy odczytu lub zapisu. Dlatego ważne jest, aby sprawdzać, czy plik został poprawnie otwarty i czy operacje wejścia/wyjścia zakończyły się sukcesem. Możemy używać metod, takich jak fail(), eof() oraz bad(), aby diagnozować problemy.

Przykład obsługi błędów
#include <fstream>
#include <iostream>

int main() {
    std::ifstream plik("dane.txt");
    if (plik.fail()) {
        std::cerr << "Błąd otwarcia pliku!" << std::endl;
        return 1;
    }

    // Odczyt danych
    if (plik.bad()) {
        std::cerr << "Błąd odczytu danych!" << std::endl;
    }

    plik.close();
    return 0;
}

W tym przykładzie używamy metody fail(), aby sprawdzić, czy plik został poprawnie otwarty, oraz metody bad(), aby wykryć błędy podczas odczytu danych.

Podsumowanie

Operacje na plikach tekstowych są niezbędne w wielu aplikacjach, od prostych programów zapisujących wyniki do zaawansowanych systemów, które muszą zarządzać danymi na dużą skalę. Znajomość sposobów otwierania, odczytu i zapisu plików oraz obsługi błędów pozwala na tworzenie bardziej niezawodnych i funkcjonalnych aplikacji. Dzięki tej wiedzy będziesz mógł bezpiecznie i efektywnie pracować z danymi, które wymagają trwałego przechowywania.

Następny temat ==> Buforowanie danych: Jak działa pamięć podręczna



Spis Treści - Wstęp do programowania

Lekcja 3: Rozwiązywanie problemów i poprawność programów Lekcja 4: Praca z różnymi typami danych Lekcja 5: Obsługa plików i pamięci Lekcja 6: Zaawansowane techniki programistyczne Lekcja 7: Wskaźniki i pamięć dynamiczna Lekcja 8: Struktura kodu i abstrakcja Lekcja 9: Rekurencja i jej zastosowania Lekcja 10: Analiza wydajności algorytmów Lekcja 11: Technika "dziel i zwyciężaj" Lekcja 12: Struktury danych o dynamicznej budowie Lekcja 13: Struktury hierarchiczne: Drzewa Lekcja 14: Struktury danych z bibliotek Lekcja 15: Algorytmy z nawrotami Lekcja 16: Programowanie dynamiczne Lekcja 17: Programowanie zachłanne Lekcja 18: Praca z grafami

Jeśli chciałbyś być poinformowany o następnych kursach to zapisz się do naszego newslettera: