Czy można modyfikować pliki z danymi na maturze z informatyki?

  • Mateusz Oracz
  • 30 czerwca 2025

Jednym z najczęściej zadawanych pytań przez maturzystów z informatyki jest to, czy można zmieniać zawartość plików tekstowych z danymi podczas egzaminu. W tym artykule wyjaśnimy wszystkie wątpliwości związane z tym tematem i pokażemy, jak poprawnie radzić sobie z problematycznymi przypadkami.

Dlaczego ktoś chciałby modyfikować plik z danymi?

Istnieją dwa główne scenariusze, w których uczniowie zastanawiają się nad modyfikacją plików:

1. Błędne dane w pliku

Pierwszym przypadkiem są błędne dane na maturze. Warto jednak podkreślić, że zdarzają się one bardzo rzadko. Jeśli program nie działa poprawnie, problem zazwyczaj leży w kodzie, a nie w pliku z danymi.
Co jednak w sytuacji, gdy mamy stuprocentową pewność, że plik jest błędny? Wyobraźmy sobie, że w poleceniu napisano, iż plik zawiera wyłącznie liczby, a w rzeczywistości znajduje się tam również tekst w kilku miejscach.
W takiej sytuacji należy napisać program, który działa poprawnie dla poprawnych danych. Centralna Komisja Egzaminacyjna (CKE) ocenia zadania w sposób uwzględniający usunięcie błędnych linii. Teoretycznie można usunąć te błędne fragmenty do testów, ale takie sytuacje są rzadkie. Przed podjęciem takiej decyzji warto dokładnie przeanalizować program i polecenie.

2. Pusta linia na końcu pliku

Drugi przypadek jest znacznie częstszy i dotyczy obecności pustej linii w plikach tekstowych z danymi. To właśnie z tym problemem wiąże się większość pytań od uczniów.
Dlaczego ta pusta linia jest tak problematyczna? Problem ten dotyka głównie programy napisane w C++, dlatego skupimy się na tym języku programowania.

Przykłady, w których ostatnia linia pliku psuje wynik

Przykład 1: Matura podstawowa 2017 - zadanie 4

W zadaniu 4.1 z matury podstawowej 2017 mieliśmy plik "liczby.txt" z tysiącem trójek liczb. Zadanie polegało na policzeniu, w ilu wierszach pliku liczby są uporządkowane rosnąco.

Czy można modyfikować pliki z danymi na maturze z informatyki?

Gdy zajrzymy do pliku tekstowego, widzimy rzeczywiście tysiąc wierszy z liczbami. Jednak poza tym znajduje się tam również tysiąc pierwsza linijka, która jest pusta.

Czy można modyfikować pliki z danymi na maturze z informatyki?

Program napisany w C++ uruchamia się poprawnie i zwraca wynik 140. Na pierwszy rzut oka wszystko wygląda w porządku. Jednak gdy sprawdzamy klucz odpowiedzi, okazuje się, że poprawna odpowiedź to 139, czyli jest o 1 większa od naszego wyniku.

#include <iostream>
#include <fstream>
using namespace std;

int main() {
    ifstream plik("liczby.txt");
    ofstream zapis("wyniki4.txt");
    int a, b, c;
    int licznik = 0;

    while (!plik.eof()) {
        plik >> a >> b >> c;
        if (a < b && b < c) {
            licznik++;
        }
    }

    zapis << "a)" << endl;
    zapis << licznik << endl;

    plik.close();
    zapis.close();
    return 0;
}                        

Program wczytuje kolejne trójki liczb z pliku i sprawdza, czy druga liczba jest większa od pierwszej, a trzecia większa od drugiej. Jeśli tak, zwiększa licznik o jeden. Logika programu jest poprawna - zadanie wydaje się proste i trudno tu o błąd.
Eksperyment: Po usunięciu ostatniej pustej linijki z pliku tekstowego program zwraca poprawny wynik!

Przykład 2: Matura czerwcowa 2021 - zadanie z napisami

W zadaniu 4.1 z czerwcowej matury 2021 mieliśmy plik z tysiącem napisów składających się z pięćdziesięciu znaków. Niektóre znaki to duże litery alfabetu, inne to cyfry. Zadanie polegało na podaniu łącznej liczby cyfr we wszystkich napisach.

Czy można modyfikować pliki z danymi na maturze z informatyki?

Tak samo jak w poprzednim przykładzie - w pliku tekstowym widzimy tysiąc wierszy z danymi i ostatnią pustą linijkę numer tysiąc jeden.

Czy można modyfikować pliki z danymi na maturze z informatyki?

Program w C++ korzysta z prostej funkcji sprawdzającej, czy znak jest cyfrą (sprawdza, czy kod ASCII mieści się w odpowiednim przedziale). Dla każdego znaku każdego napisu wywołuje funkcję i zwiększa zmienną liczącą cyfry. Po uruchomieniu otrzymujemy wynik 11 854.

#include <iostream>
#include <fstream>
using namespace std;

bool czyJestCyfra(char znak) {
    return znak >= '0' && znak <= '9';
}

int main() {
    ifstream plik("napisy.txt");
    ofstream zapis("wyniki4.txt");
    string linia;
    int liczbaCyfr = 0;

    while (!plik.eof()) {
        plik >> linia;

        for (int i = 0; i < linia.length(); i++) {
            if (czyJestCyfra(linia[i])) {
                liczbaCyfr++;
            }
        }
    }

    zapis << "a)" << endl << liczbaCyfr << endl;

    plik.close();
    zapis.close();

    return 0;
}

I znowu niespodzianka! Poprawny wynik to 11 844 - o 10 mniej od naszego wyniku.
Analogicznie jak w poprzednim zadaniu - po usunięciu pustej linijki z pliku tekstowego wynik staje się poprawny.

Dlaczego pusta linijka jest problematyczna?

Aby zrozumieć problem, przeanalizujmy jak działa proces odczytywania pliku przez C++:

  1. Odczyt normalnych linii: Wartości wczytane z linii zostają umieszczone w zmiennych. Funkcja plik.eof() zwraca false, więc pętla wykonuje się dalej.
  2. Ostatnia niepusta linia: Wartości zmiennych zostają poprawnie zaktualizowane.
  3. Próba odczytu pustej linijki: Operator ekstrakcji danych >> pomija białe znaki, więc wartości zmiennych NIE ZOSTAJĄ ZAKTUALIZOWANE, ale pętla nadal je przetwarza.
  4. Końcowy efekt: Przedostatnia linia pliku zostaje przetworzona dwukrotnie, ponieważ program analizuje ją raz po prawidłowym odczycie, a drugi raz po nieudanej próbie odczytu pustej linii.
Dopiero po próbie odczytu ostatniej linii plik.eof() zwraca true i kończy się wykonywanie pętli.

Kluczowa zasada

Metoda eof() (end of file) nie zostanie ustawiona na true dopóki nie nastąpi próba odczytu poza końcem pliku. Gdy ostatnia linijka jest pusta, po wczytaniu przedostatniej linijki eof() nadal zwraca false. Pętla wykonuje się ponownie i próbuje wczytać pustą ostatnią linijkę, ale operacja kończy się niepowodzeniem. Dane z przedostatniej linijki pozostają w zmiennej i są przetwarzane po raz drugi, zanim eof() zostanie ustawione na true.

Czy można modyfikować pliki na maturze?

Odpowiedź brzmi: NIE.

Dowody z oficjalnych źródeł:

1. Informacje w najnowszych maturach:
Pod koniec poleceń czytamy: "Pamiętaj, że Twój program musi ostatecznie zadziałać na pliku liczby.txt z 3000 liczb w pierwszym wierszu." To oznacza, że na maturze program musi zadziałać dla oryginalnego pliku.

Czy można modyfikować pliki z danymi na maturze z informatyki?

2. Informacja ze strony 7. informatora maturalnego o egzaminie maturalnym z informatyki:

Czy można modyfikować pliki z danymi na maturze z informatyki?

Z tego punktu wprost wynika, że programy będą testowane przez egzaminatorów. Na maturze do oceny oddajemy wyłącznie program - plików tekstowych z danymi już nie.
Konsekwencje: Jeśli usuniemy pustą linię z pliku, program będzie działał poprawnie podczas naszych testów. Jednak egzaminator do testów użyje oryginalnego pliku z problematyczną pustą linią. Program zwróci błędny wynik i zgodnie z informatorem możemy nie otrzymać punktów za zadanie.

Jak poprawnie rozwiązać problem?
Opcja 1: Użycie metody fail()

Zostawiamy warunek !plik.eof(), wczytujemy kolejne liczby za pomocą operatorów ekstrakcji plik >> a >> b >> c i przed wykonywaniem kodu dotyczącego warunku umieszczamy instrukcję if z plik.fail() oraz break; w środku:

#include <iostream>
#include <fstream>
using namespace std;

int main() {
    ifstream plik("liczby.txt");
    ofstream zapis("wyniki4.txt");
    int a, b, c;
    int licznik = 0;

    while (!plik.eof()) {
        plik >> a >> b >> c;
        if (plik.fail()) break;
        if (a < b && b < c) {
            licznik++;
        }
    }

    zapis << "a)" << endl;
    zapis << licznik << endl;

    plik.close();
    zapis.close();
    return 0;
}
                        

Podczas próby odczytu pustej linii plik.fail() zwróci true i pętla zostanie przerwana.

Opcja 2: Przeniesienie odczytu do warunku pętli

W ten sposób program będzie wczytywał dane dopóki jest coś do wczytania:

#include <iostream>
#include <fstream>
using namespace std;

bool czyJestCyfra(char znak) {
    return znak >= '0' && znak <= '9';
}

int main() {
    ifstream plik("napisy.txt");
    ofstream zapis("wyniki4.txt");

    string linia;
    int liczbaCyfr = 0;

    while (plik >> linia) {
        for (int i = 0; i < linia.length(); i++) {
            if (czyJestCyfra(linia[i])) {
                liczbaCyfr++;
            }
        }
    }

    zapis << "a)" << endl << liczbaCyfr << endl;

    plik.close();
    zapis.close();

    return 0;
}

Uwaga: Zapis plik >> linia powinien znajdować się TYLKO w warunku pętli. Umieszczenie go także wewnątrz pętli spowoduje, że w każdej iteracji będą odczytywane dwie linijki - jedna przez warunek, druga przez wywołanie wewnątrz pętli. Przez to połowa linii z pliku zostanie pominięta.

Opcja 3: Użycie funkcji getline()

Ta metoda jest szczególnie przydatna, gdy pracujemy z całymi liniami tekstu zawierającymi spacje:

#include <iostream>
#include <fstream>
using namespace std;

bool czyJestCyfra(char znak) {
    return znak >= '0' && znak <= '9';
}

int main() {
    ifstream plik("napisy.txt");
    ofstream zapis("wyniki4.txt");

    string linia;
    int liczbaCyfr = 0;

    while (getline(plik, linia)) {
        for (int i = 0; i < linia.length(); i++) {
            if (czyJestCyfra(linia[i])) {
                liczbaCyfr++;
            }
        }
    }

    zapis << "a)" << endl << liczbaCyfr << endl;

    plik.close();
    zapis.close();

    return 0;
}

Pamiętajmy, żeby nie dodawać getline() także wewnątrz pętli - ma być tylko w warunku.

Podsumowanie

Na maturze z informatyki nie można modyfikować plików z danymi. Zgodnie z wymaganiami CKE program powinien działać dla oryginalnego pliku tekstowego z danymi, ponieważ egzaminatorzy będą testować rozwiązania na oryginalnych plikach, a być może także na dodatkowych zestawach testowych.
Kluczem do sukcesu jest napisanie kodu, który poprawnie radzi sobie z problematycznymi przypadkami, takimi jak puste linie na końcu pliku. Przedstawione powyżej metody pozwalają na stworzenie programów odpornych na tego typu problemy, co zapewnia poprawne działanie zarówno podczas własnych testów, jak i podczas oficjalnej oceny przez egzaminatorów.

Powiązane artykuły :
Czy można używać własnego sprzętu na maturze z informatyki?
Czy można używać własnego sprzętu na maturze z informatyki?
Artykuł
Funkcje wbudowane na maturze z informatyki – jak nie stracić punktów?
Funkcje wbudowane na maturze z informatyki – jak nie stracić punktów?
Artykuł