Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Lekcja 32 - getline, a kilka wersów

Ostatnio zmodyfikowano 2014-08-22 20:03
Autor Wiadomość
Marcinxxl2
Temat założony przez niniejszego użytkownika
Lekcja 32 - getline, a kilka wersów
» 2014-08-22 02:02:14
Hejka, mam teraz takie pytanie raczej nie związane z zadaniem domowym. Chodzi mi o to, w jaki sposób działa getline, gdy odczytujemy jakiś plik tesktowy, a raczej jak on zapisuje (albo nie zapisuje) kilka wersów.

Wiem, że to działa tak:

C/C++
getline( plik, miejsce_do_zapisu );

Po wykonaniu tego polecenia pierwszy wers z pliku "plik" zostanie zapisany do string' a "miejsce_do_zapisu". Jeśli plik "plik" ma kilka wersów, i tak zapisany zostanie tylko pierwszy. Jednak po wykonaniu takiego polecenia:

C/C++
while( getline( plik, miejsce_do_zapisu ) )
{
    cout << miejsce_do_zapisu << endl;
}

Zostaną wyświetlone wszystkie wersy pliku "plik".

Zastanawiam się więc, dlaczego jeśli można wypisać cały plik, dlaczego nie można wpisać całego pliku do zmiennej (a może do kilku zmiennych, bo się w jednej nie zmieści, lub do tablicy), a także po co jest ta pętla i dlaczego działa, jeśli nie ma zadeklarowanej żadnej informacji o tym, kiedy ma się skończyć...

Mam nadzieje, że ktoś mi to jakoś wytłumaczy, gdyż chce się o tym dowiedzieć zanim pójdę do następnej lekcji (no i jest mi to potrzebne do rozwiązania zadania domowego). Z góry dziękuje za odpowiedzi :)
  

P-115927
alixir
» 2014-08-22 09:39:06
W pierwszym przypadku wywołujesz funkcję getline jednokrotnie, dlatego dostajesz jeden wiersz z pliku.

W drugim przypadku jak sam zauważyłeś jest pętla, która wykonuje się tyle razy ile wierszy masz w pliku. Za każdym razem pobiera ona nowy wiersz i zapisuje do zmiennej, którą następnie wyświetla, stąd widzisz zawartość całego pliku na ekranie.

po co jest ta pętla i dlaczego działa, jeśli nie ma zadeklarowanej żadnej informacji o tym, kiedy ma się skończyć...
Warunek pętli jest ściśle określony i doskonale wie jak długo ma się wykonywać.

Dla celów edukacyjnych możesz sobie zmodyfikować zapis pętli

C/C++
while( getline( plik, miejsce_do_zapisu ) )
{
    cout << miejsce_do_zapisu << endl;
    cin.get();
   
}

W każdym obiegu pętli będziesz musiał wcisnąć Enter, co da ci pojęcie ile razy wykonuje się pętla.
Lub możesz nawet dla testów napisać coś takiego, co mam nadzieję rozjaśni ci trochę sytuację:
C/C++
getline( plik, miejsce_do_zapisu );
cout << miejsce_do_zapisu << endl;

getline( plik, miejsce_do_zapisu );
cout << miejsce_do_zapisu << endl;

getline( plik, miejsce_do_zapisu );
cout << miejsce_do_zapisu << endl;

Zastanawiam się więc, dlaczego jeśli można wypisać cały plik, dlaczego nie można wpisać całego pliku do zmiennej
Można.
P-115929
pekfos
» 2014-08-22 10:13:11
Zastanawiam się więc, dlaczego jeśli można wypisać cały plik, dlaczego nie można wpisać całego pliku do zmiennej
Można.
C/C++
std::string str { std::istreambuf_iterator < char >( plik.rdbuf() ), std::istreambuf_iterator < char >() };

(a może do kilku zmiennych, bo się w jednej nie zmieści, lub do tablicy)
Dlaczego miałby się nie zmieścić w jednej?

P-115932
Marcinxxl2
Temat założony przez niniejszego użytkownika
» 2014-08-22 20:03:52
Och, okej, wielkie dzięki :) Już rozumiem. A z tym dlaczego miało być kilka zmiennych chodziło mi o to, że może po prostu string'i mają już tak wbudowane, że maksymalnie może być jeden wers, ale na szczęście nie :)

Edit:

Jest! Chyba działa (zadanie domowe) :D Wielkie dzięki za pomoc.

C/C++
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main()
{
    string wyszukiwana_fraza;
    string tekst;
    ifstream plik;
    plik.open( "C:\\magic.txt" );
    if( plik.good() )
    {
        cout << "Podaj wyszukiwana fraze" << endl;
        cin >> wyszukiwana_fraza;
        while( getline( plik, tekst ) )
        {
            if( tekst.find( wyszukiwana_fraza ) != string::npos )
            {
                cout << tekst << endl;
            }
            else
            {
                cout << "Nie znaleziono" << endl;
            }
        }
    }
    else
    {
        cout << "Nie udalo sie wcztac pliku" << endl;
    }
    plik.close();
}

Co ciekawe, wcześniej zrobiłem też chyba działający dobrze program, który nie wykorzystuje jednak tego polecenia "while ( getline( plik, tekst ) ), a też teoretycznie jest zgodny z poleceniem (trzeba jedynie znać liczbę wersów w pliku), ale ten wygląda lepiej.
P-115973
« 1 »
  Strona 1 z 1