P-Programowanie

Odczyt danych z pliku C++

Ostatania modyfikacja: 13 sierpnia 2014, kategoria: Matura z informatyki

Odczytywanie plików w C++ jest jedną z podstawowych operacji jakie musisz umieć, przed przystąpieniem do matury z informatyki. Pliki można odczytywać w trybie binarnym lub tekstowym. Można wczytywać liniami oraz blokami za pomocą wskaźników ustawianych w pliku. Na maturze przyda się jedynie odczytywanie pliku w trybie tekstowym, najlepiej pojedynczymi liniami.

Odczytywanie danych z pliku C++

Program otwiera podany przez nas plik i sprawdza czy nie wystąpiły błędy. Jeżeli wszystko jest w porządku, rozpoczyna się wczytywanie danych za pomocą funkcji getline. Funkcja wywołana jest w pętli wykonującej się póki plik nie osiągnie końca (eof).

Kod w C++

Otwarliśmy plik używając nagłówka biblioteki <fstream> oraz wykorzystując zmienną fstream. Ponieważ tylko wczytujemy tekst z pliku moglibyśmy użyć biblioteki <ifstream>. Nazwy pochodzą od języka angielskiego:

  • ifstream = in file stream = wczytywanie plików
  • ofstream = out file stream = zapisywania plików
  • fstream = połączenie obu powyższych

Na maturze bardzo wygodnie wczytywać plik w podany przeze mnie sposób. W pętli dostajemy pojedyncze linijki, na których możemy wykonywać różne operacje. Gdyby to były liczby, można zamieniać je na binarne lub dziesiętne, ze słów można od razu robić palindromy i anagramy.

Użytkownik Ocet napisał:

24 marca 2013


A jak wyglądały by wczytywanie danych oddzielonych znakiem specjalnym? Np. mając w jednej linii:
abcd bdca abac

Użytkownik Karol napisał:

24 marca 2013


Jeżeli masz w zadaniu maturalnym ciągi znaków oddzielone spacjami w postaci:

aa bb cc
dd ee ff
itd..

to możesz użyć strumienia:


#include
#include
#include

using namespace std;

int main()
{
fstream plik;
string slowo1, slowo2, slowo3;

plik.open( "dane.txt", ios::in | ios::out );
if( plik.good() == true )
{
while (!(plik.eof()))
{
plik >> slowo1 >> slowo2 >> slowo3;
cout < < slowo1 << endl; cout << slowo2 << endl; cout << slowo3 << endl; } plik.close(); } return( 0 ); }

Należy być ostrożnym używając strumienia. Wszytko może się rozsypać jeżeli jedna linijka będzie miała np. 4 wyrazy a pozostałe 3. Funkcji wbudowanej do rozdzielania tekstu po określonych znakach niestety nie ma.

Użytkownik Ocet napisał:

25 marca 2013


Dziękuję za odpowiedź.

Użytkownik Kuba napisał:

15 maja 2013


Tak dla uściślenia:
1) Według mnie lepiej używać przekierowania pliku txt do naszego zadania (ściślej .exe) przez plik typu b, bo oszczędzamy czas. Można to robić przez konsole cmd ( pisze za 1 tydzien tą mature, i bede korzystał z cmd do testowania, a egzaminatorowi zostawie info jak odpalić i zrobie .bat czyli przekierowanie).
2) ze strumieniami jest taki problem że czasem liczą źle
3) jak ma się dwa pliki np. matura 2012 to nalezy je złączyć w excelu w jeden

Uważam, że moja metoda jest poprawna, szybsza oraz przede wszystkim mniej awaryjna

Użytkownik Karol napisał:

15 maja 2013


Nie wiem o co chodzi w Twojej metodzie ale wierzę, że jest skuteczna :) Strumień wyjścia/wejścia jest prosty jak budowa cepa, rzadko się wysypuje.

Osobiście wolał bym nie kombinować z plikami wsadowymi, awaryjność wtedy wydaje mi się większa. Jakieś instrukcje dla egzaminatorów? On nawet nie ma powiedziane że ma szukać jakiś instrukcji. Odpali program okaże się że nie działa, zobaczy jakieś pliki wsadowe. Od jego dobrej woli będzie zależało czy zmarnuje 20 minut na czytanie Twoich instrukcji czy da Ci 0 pkt.

Weź pod uwagę, że egzaminator sprawdza zadania machinalnie, rzadko kiedy zagłębia się w kod. Maturki sprawdzają zwykli nauczyciele informatyki, wielu z nich umie jedynie obsługiwać z trudnością Pakiet Office.

Użytkownik Maya napisał:

19 maja 2014


Super blog :P właśnie uczę się do matury z informatyki i dużo mi to pomogło.

Użytkownik Bartek napisał:

10 marca 2015


załóżmy że mamy po 120 liczb w jednej lini, i mamy zapisac do pliku te liczby ktore mają taką samą długosc jakby wyglądał taki kod ? bo wiadomo ze nikt nie bedzie robil 120 zmiennych mierzyl dlugosc i porownywał, a czy uzywajac funckji getline dałoby sie cos takiego zrobic ?

Użytkownik Karol napisał:

10 marca 2015


Zapisywanie liczb, które mają taką samą długość w jednej linii? Podane przez Ciebie polecenie brzmi dość dziwnie. Zawsze w przypadku operowania na wielu danych tego samego typu, korzystamy z tablic. Ciężko byłoby zadeklarować 120 zmiennych jak słusznie zauważyłeś, ale nie będzie problemem utworzenie tablicy 120 elementowej typu int -> wczytanie do niej danych -> a następnie przetwarzanie w pętli for każdego elementu według jakiś kryteriów (np. długości).

Użytkownik Bartek napisał:

10 marca 2015


dzisiaj miałem takie zadanko na lekcji ze w jakimś tam pliku znajduje sie 200 wierszy po 2 wyrazy w kazdym wierszu i mialem :
a) z kazdego wiersza znalezc dluzsza cyfre i zapisac ją do pliku jakiegos tam,
b) sprawdzic czy cyfry są anagramami palindromami
c) zapisac do pliku cyfry o tej samej dlugosci,
szczerze mowiąc zadanie na pcozatku wydało mi sie banalne bo algorytmy na palindrom anagram max znam, ale mam jakos problem z tą oblugą plikow wiem wszystko ifstream ofstream eof itd ale jakos mam problem z wyobrazeniem sobie jak to ugryzc moglbys napisac mi liste krokow jak Ty byś zabrał sie do tego zadanka ?

Użytkownik Karol napisał:

11 marca 2015


Lista kroków służy do przedstawienia działania algorytmu a nie złożonego programu. Wszystkie potrzebne materiały służące do wykonania zadania znajdują się na tym blogu. Wczytujesz w pętli 200 wierszy do dwóch różnych tabel typu string. Cała ta pętla jest przedstawiona w przykładzie właśnie na tej stronie wyżej. Po wczytaniu metoda działania pozostaje oczywista. Puszczasz kilka pętli z licznikiem 0..199 i operujesz na poszczególnych elementach tablic. Sprawdzasz czy są równe, czy są palindromami, czy są anagramami.

Nie staraj się wszystkiego zrobić w jednej pętli, rozbijaj zadanie na jak największą ilość funkcji. Ciągle używasz terminu cyfry, a nie ma tu żadnych cyfr tylko ciągi znaków => a więc wczytuj dane w formacie string, bez żadnych konwersji na int.

PS. Oczywiście wczytujesz dane do dwóch różnych tabel, ponieważ w każdej linijce są dwa słowa. Wczytujesz CAŁĄ linijkę do zmiennej string -> następnie rozbijasz na dwa wyrazu (spacja jest sepatorem), a następnie dwa wyrazy lądują do dwóch osobnych tablic. Dzięki temu masz pewność i łatwość porównywania, ponieważ indeksy tabel odpowiadają sąsiadującym wyrazom (tabA[87] to para dla tabB[87] a z tego wynika łatwość porównywania dwóch wyrazów np. if (tabA[i]==tabB[i]) …

Użytkownik Bartek napisał:

11 marca 2015


Aha, ok wiem, ze tu sa ciagi znakow po prostu przez ostatnie pol roku wsztstkie dzialania byly tylko i wylacznie na liczbach wiec jakies takie przyzwyczajenie mam ze jak cos robimy to liczby, jak chce wczytac sobie jedna liczbe do tabeli a druga do drugiej tabeli to. while(!in.eof())
{
in>>tabA[0]>>tabB[0];
tabA++;
tabB++;
}
W taki sposob ?

Użytkownik Karol napisał:

11 marca 2015


Ojojoj. Stawiam, że takie przewijanie wskaźników na 99% nie zadziała. Dlaczego tak kombinujesz? Albo totalnie nie wiesz jak działają tablice, albo totalnie przekombinowałeś zadanie i próbujesz arytmetycznie przewijać wskaźnik na 1 element tablicy? Hmm.. Zadania maturalne polecam robić jak najmniejszym nakładem sił, aby czasem się nie zaplątać, każda minuta się liczy.

Zastosowałeś fajny zabieg dzielenia stringa na spacje za pomocą operatora strumienia (>>), jednak dlaczego wszystkie wyrazy zapisujesz w pierwszym elemencie tablicy? Zrób pomocniczą zmienną „i”, i inkrementuj ją co jeden obieg pętli „in >> tabA[i] >> tabB[i]”. Kod będzie krótszy, prostszy i na 100% zadziała.

Obowiązkowo przeczytaj o tablicach w języku C++, z jakiegoś podstawowego kursu. Bez tego nie ruszysz.

Użytkownik Bartek napisał:

11 marca 2015


Tak myslalem mam problem z tablicami jakos iezko mi to sobie wyobrazic

Użytkownik Arek napisał:

12 kwietnia 2016


A jak zapisać plik skompresowany np. rar?

Użytkownik marcinms24 napisał:

24 października 2017


Czy jest możliwe odczytanie znaku o konkretnych współrzędnych? Np. 3. wierz, 4. kolumna, albo powiedzmy 5. wiersz i 3. łańcuch znaków? Oczywiście można by wczytywać w pętli kolejne elementy i zadziałać na wskazanym, ale chciałbym pominąć te wcześniejsze odczytywanie.

Użytkownik Karol napisał:

25 października 2017


@Marcinms24
Nie znam takiego sposobu, ani nie słyszałem, żeby ktoś z moich znajomych takiej metody używał. Rozmawiając w kontekście matury z informatyki, zadania przeważnie są ułożone tak, że dla maturzysty wręcz lepiej wczytywać dane linijka po linijce. W innych przypadkach takie wczytywanie w ogóle raczej nie ma sensu, lepiej wczytać cały plik binarnie do bufora, a dopiero później nim manipulować.

Użytkownik Ciapek napisał:

23 października 2018


Czy istnieje możliwość odczytu danych z pliku używając tylko i wyłącznie standardowego wejścia?

Zachęcam Cię do zostawienia komentarza!

Ilość znaków: 0