Twoje Centrum Szkoleniowe

Nauczmy się dziś czegoś nowego!

Kurs programowania - C++

C++: Odczyt plików tekstowych

Czytanie danych z plików tekstowych w C++ może być realizowane na różne sposoby, w zależności od potrzeb i struktury danych. Dwie podstawowe metody to użycie getline do czytania całych linii tekstu oraz operatora >> do czytania pojedynczych elementów, jak słów czy wartości numerycznych.

 

Getline
  • getline jest używany do czytania całej linii tekstu aż do napotkania znaku nowej linii (\n).
  • Jest to szczególnie przydatne, gdy chcemy zachować formatowanie linii lub przeczytać linię zawierającą przecinki, spacje lub inne separatory.
string linia;
ifstream plik("plik.txt");
while (getline(plik, linia)) {
    cout << linia << endl;
}

 

Operator ekstrakcji >>
  • Operator ekstrakcji >> jest używany do czytania pojedynczych elementów danych, takich jak słowa czy liczby.
  • Automatycznie ignoruje białe znaki, w tym spacje i znaki nowej linii.
string slowo;
ifstream plik("plik.txt");
while (plik >> slowo) {
    cout << slowo << endl;
}

 

Kombinacje metod czytania

W praktyce często łączy się różne metody czytania, aby osiągnąć pożądany efekt. Na przykład, można używać getline do czytania linii, a następnie strumień stringstream w kombinacji z operatorem >> do ekstrakcji poszczególnych wartości z tej linii.

string linia, slowo;
ifstream plik("plik.txt");
while (getline(plik, linia)) {
    stringstream ss(linia);
    while (ss >> slowo) {
        cout << slowo << " ";
    }
    cout << endl;
}

Taka kombinacja jest szczególnie użyteczna w przypadku przetwarzania plików z danymi strukturalnymi, takimi jak CSV, gdzie każda linia zawiera wiele oddzielonych przecinkami wartości.

 

Typowe problemy przy czytaniu plików

 

Koniec pliku (EOF)

Jednym z głównych problemów podczas czytania plików jest dotarcie do końca pliku (EOF). W C++, strumień pliku staje się "fałszywy" (false), kiedy osiągnie koniec pliku, co może być wykorzystane do kontroli pętli czytającej.

ifstream plik("plik.txt");
string linia;
while (getline(plik, linia)) {
    // Czytanie linii do końca pliku
}

 

Możemy również sprawdzić, czy dotarliśmy do końca pliku

if (inputFile.eof()) {
        cout << "Koniec pliku osiągnięty." << endl;
    }

 

Puste linie

Czytanie pliku może również napotkać puste linie, które mogą być albo pomijane, albo traktowane jako ważne w zależności od kontekstu aplikacji.

if (linia.empty()) {
    // Pomijanie pustej linii
}

 

Sprawdzanie poprawności strumienia

Ważne jest, aby sprawdzać, czy strumień pliku został poprawnie otwarty i czy nie napotkał błędów podczas operacji odczytu.

ifstream plik("plik.txt");
if (!plik) {
    cerr << "Nie można otworzyć pliku." << endl;
    // Obsługa błędu
}

 

Obsługa błędów podczas czytania

Podczas czytania z pliku, należy być przygotowanym na różne scenariusze, takie jak nieoczekiwane formatowanie danych czy brak oczekiwanych wartości.

int liczba;
while (plik >> liczba) {
    if (plik.fail()) {
        // Obsługa błędu podczas czytania liczby
    }
}

 

Przykłady praktyczne odczytu plików tekstowych

 

Czytanie całych linii tekstu

 

Zawartość pliku tekst.txt:

Wiersz 1
Wiersz 2
Wiersz 3
Wiersz 4
Wiersz 5

 

Kod:

#include <fstream>
#include <iostream>
#include <string>

int main() {
    std::ifstream plik("tekst.txt");
    std::string linia;
    while (std::getline(plik, linia)) {
        std::cout << linia << std::endl;
    }
    return 0;
}

 

Wynik działania:

Wiersz 1
Wiersz 2
Wiersz 3
Wiersz 4
Wiersz 5

 

Analiza kodu:

  1. #include <fstream>

    • Ta linia dołącza bibliotekę <fstream>, która zawiera klasy do pracy z plikami, takie jak std::ifstream (input file stream) do czytania z plików.
       
  2. #include <iostream>

    • Dołącza standardową bibliotekę wejścia-wyjścia, która pozwala na operacje wejścia-wyjścia, np. wypisywanie danych na ekranie za pomocą std::cout.
       
  3. #include <string>

    • Ta linia dołącza bibliotekę <string>, umożliwiając korzystanie z typu std::string, który reprezentuje ciągi znaków.
       
  4. int main()

    • Początek głównej funkcji programu. Każdy program w C++ musi zawierać funkcję main, która jest punktem startowym programu.
       
  5. std::ifstream plik("tekst.txt");

    • Tworzy obiekt plik klasy std::ifstream, który otwiera plik tekst.txt do czytania. Jeśli plik nie istnieje lub nie może być otwarty, obiekt będzie w stanie błędu.
       
  6. std::string linia;

    • Deklaruje zmienną linia typu std::string. Zmienna ta będzie używana do przechowywania każdej przeczytanej linii z pliku.
       
  7. while (std::getline(plik, linia))

    • Pętla while używa funkcji std::getline, aby czytać każdą linię z pliku. Funkcja ta zwraca false, gdy dojdzie do końca pliku lub wystąpi błąd, kończąc pętlę.
       
  8. std::cout << linia << std::endl;

    • Wypisuje przeczytaną linię (linia) na standardowe wyjście (konsolę) i dodaje znak nowej linii na końcu.
       
  9. return 0;

    • Zakończenie funkcji main zwracającej 0, co jest konwencjonalnym sposobem sygnalizowania, że program zakończył działanie pomyślnie.

 

Podsumowując, program otwiera plik tekstowy do czytania, a następnie czyta i wypisuje jego zawartość linia po linii na ekran.

 

 

Czytanie pojedynczych słów

 

Zawartość pliku tekst.txt:

Słowo1 Słowo2
Słowo3 Słowo4
Słowo5

 

Kod:

#include <fstream>
#include <iostream>
#include <string>

int main() {
    std::ifstream plik("tekst.txt");
    std::string slowo;
    while (plik >> slowo) {
        std::cout << slowo << std::endl;
    }
    return 0;
}

 

Wynik działania:

Słowo1
Słowo2
Słowo3
Słowo4
Słowo5

 

Analiza kodu:

  1. #include <fstream>

    • Ta linia dołącza bibliotekę <fstream>, niezbędną do korzystania z funkcji wejścia-wyjścia plików w C++, w tym klasy std::ifstream.
       
  2. #include <iostream>

    • Dołącza standardową bibliotekę wejścia-wyjścia, umożliwiając korzystanie z std::cout do wypisywania na standardowe wyjście (konsolę).
       
  3. #include <string>

    • Dołącza bibliotekę <string>, co pozwala na korzystanie z typu std::string do przechowywania ciągów znaków.
       
  4. int main()

    • Początek głównej funkcji programu, będącej punktem wejścia każdego programu w C++.
       
  5. std::ifstream plik("tekst.txt");

    • Tworzy obiekt plik klasy std::ifstream, który otwiera plik tekst.txt do czytania.
       
  6. std::string slowo;

    • Deklaruje zmienną slowo typu std::string, która będzie używana do przechowywania każdego przeczytanego słowa z pliku.
       
  7. while (plik >> slowo)

    • Pętla while czyta pojedyncze słowa z pliku za pomocą operatora >> i zapisuje je do zmiennej slowo. Pętla kontynuuje, dopóki są dostępne słowa w pliku.
       
  8. std::cout << slowo << std::endl;

    • Wypisuje przeczytane słowo (slowo) na konsolę i dodaje znak nowej linii na końcu.
       
  9. return 0;

    • Zwraca wartość 0 na zakończenie funkcji main, sygnalizując pomyślne zakończenie programu.
       

Podsumowując, program otwiera plik tekstowy do czytania, a następnie czyta i wypisuje każde słowo z pliku osobno, jedno po drugim, na ekranie. Każde słowo jest oddzielone od następnego standardowymi separatorami, takimi jak spacje, znaki nowej linii itp.

 

 

Czytanie danych konfiguracyjnych

 

Zawartość pliku config.txt:

klucz1 wartość1
klucz2 wartość2
klucz3 wartość3
klucz4 wartość4
klucz5 wartość5

 

Kod:

#include <fstream>
#include <iostream>
#include <string>

int main() {
    std::ifstream plikKonfig("config.txt");
    std::string klucz, wartosc;
    while (plikKonfig >> klucz >> wartosc) {
        std::cout << "Klucz: " << klucz << ", Wartość: " << wartosc << std::endl;
    }
    return 0;
}

 

Wynik działania:

Klucz: klucz1, Wartość: wartość1
Klucz: klucz2, Wartość: wartość2
Klucz: klucz3, Wartość: wartość3
Klucz: klucz4, Wartość: wartość4
Klucz: klucz5, Wartość: wartość5

 

Analiza kodu:

  1. #include <fstream>

    • Ta linia dołącza bibliotekę <fstream>, która zawiera funkcje i klasy do pracy z plikami, w tym std::ifstream.
       
  2. #include <iostream>

    • Dołącza bibliotekę standardowego wejścia-wyjścia, umożliwiając korzystanie z std::cout do wypisywania na konsolę.
       
  3. #include <string>

    • Dołącza bibliotekę <string>, co pozwala na korzystanie z typu std::string.
       
  4. int main()

    • Definiuje funkcję main, punkt startowy programu.
       
  5. std::ifstream plikKonfig("config.txt");

    • Tworzy obiekt plikKonfig klasy std::ifstream, który otwiera plik o nazwie config.txt w celu jego odczytu.
       
  6. std::string klucz, wartosc;

    • Deklaruje dwie zmienne typu std::string, które będą przechowywać klucze i ich wartości przeczytane z pliku konfiguracyjnego.
       
  7. while (plikKonfig >> klucz >> wartosc)

    • Pętla czyta kolejne pary klucz-wartość z pliku konfiguracyjnego. Oczekuje się, że każda para będzie oddzielona białym znakiem (np. spacją).
       
  8. std::cout << "Klucz: " << klucz << ", Wartość: " << wartosc << std::endl;

    • Wypisuje przeczytaną parę klucz-wartość na ekranie konsoli.
       
  9. return 0;

    • Zwraca wartość 0, sygnalizując poprawne zakończenie programu.
       

Podsumowując, program odczytuje pary klucz-wartość z pliku konfiguracyjnego, gdzie każda para jest oddzielona białym znakiem, a następnie wypisuje te pary na ekranie. 

 

Czytanie plików CSV

 

Zawartość pliku dane.csv:

1,2,3
4,5,6
7,8,9
10,11,12
13,14,15

 

Kod:

#include <fstream>
#include <iostream>
#include <sstream>
#include <string>

int main() {
    std::ifstream plikCSV("dane.csv");
    std::string linia;
    while (std::getline(plikCSV, linia)) {
        std::stringstream ss(linia);
        std::string item;
        while (std::getline(ss, item, ',')) {
            std::cout << item << std::endl;
        }
    }
    return 0;
}

 

Wynik działania:

1
2
3
4
5
(i tak dalej dla każdej wartości)

 

Analiza kodu:

  1. #include <fstream>

    • Dołącza bibliotekę do obsługi plików, co umożliwia korzystanie z std::ifstream do odczytu plików.
       
  2. #include <iostream>

    • Dołącza standardową bibliotekę wejścia-wyjścia, dzięki której można używać std::cout.
       
  3. #include <sstream>

    • Dołącza bibliotekę sstream, która pozwala na korzystanie z std::stringstream. Używana jest do przetwarzania poszczególnych linii tekstu.
       
  4. #include <string>

    • Dołącza bibliotekę string, która udostępnia typ std::string.
       
  5. int main()

    • Funkcja główna programu, od której rozpoczyna się jego wykonanie.
       
  6. std::ifstream plikCSV("dane.csv");

    • Otwiera plik dane.csv do odczytu. Przyjmuje się, że jest to plik w formacie CSV.
       
  7. std::string linia;

    • Deklaruje zmienną typu std::string do przechowywania pojedynczej linii tekstu z pliku.
       
  8. while (std::getline(plikCSV, linia))

    • Pętla czyta kolejne linie tekstu z pliku CSV. Każda linia jest wczytywana do zmiennej linia.
       
  9. std::stringstream ss(linia);

    • Tworzy stringstream na podstawie przeczytanej linii. Pozwala to na oddzielanie poszczególnych wartości w linii.
       
  10. std::string item;

    • Deklaruje zmienną typu std::string do przechowywania poszczególnych wartości rozdzielonych przecinkami.
       
  11. while (std::getline(ss, item, ','))

    • Pętla wewnątrz pętli: czyta każdą wartość oddzieloną przecinkiem (',') z linii.
       
  12. std::cout << item << std::endl;

    • Wypisuje każdą przeczytaną wartość na standardowe wyjście.
       
  13. return 0;

    • Kończy działanie programu zwracając 0.

 

Podsumowując, program odczytuje plik w formacie CSV, rozdziela wartości na podstawie przecinków, a następnie wypisuje każdą wartość w osobnej linii na ekran. 

 

 

Analiza wyników

 

Zawartość pliku dane.txt:

10
20
30
40
50

 

Kod:

#include <fstream>
#include <iostream>

int main() {
    std::ifstream plikDanych("dane.txt");
    int suma = 0, liczba;
    while (plikDanych >> liczba) {
        suma += liczba;
    }
    std::cout << "Suma: " << suma << std::endl;
    return 0;
}

 

Wynik działania:

Suma: 150

 

Analiza kodu:

  1. #include <fstream>

    • Dołączenie biblioteki fstream, która umożliwia korzystanie z funkcji do odczytu plików (std::ifstream).
       
  2. #include <iostream>

    • Dołączenie standardowej biblioteki wejścia-wyjścia, dzięki której można używać std::cout do wypisywania na konsolę.
       
  3. int main()

    • Początek głównej funkcji programu, od której rozpoczyna się jego wykonanie.
       
  4. std::ifstream plikDanych("dane.txt");

    • Otwiera plik o nazwie "dane.txt" w trybie odczytu. Plik ten powinien zawierać liczby oddzielone spacjami lub znakami nowej linii.
       
  5. int suma = 0, liczba;

    • Deklaracja dwóch zmiennych typu int: suma inicjowana na 0 do przechowywania sumy liczb i liczba do przechowywania każdej odczytanej liczby z pliku.
       
  6. while (plikDanych >> liczba)

    • Pętla while kontynuuje działanie, dopóki istnieją liczby do odczytania z pliku. Operator >> wczytuje kolejne liczby do zmiennej liczba.
       
  7. suma += liczba;

    • Dodaje każdą odczytaną liczbę do zmiennej suma.
       
  8. std::cout << "Suma: " << suma << std::endl;

    • Wypisuje na standardowe wyjście sumę wszystkich odczytanych liczb z pliku.
       
  9. return 0;

    • Kończy działanie programu zwracając wartość 0.

 

Program ten sumuje wszystkie liczby z pliku tekstowego i wypisuje wynik na ekran.

Testy przypięte do lekcji
Aby uzyskać dostęp do testów i ćwiczeń interaktywnych - Zaloguj się
Aby widzieć ocenę lekcji - Zaloguj się