Wykrywanie frazy w tekście

0

Moim zadaniem jest napisać program, który odczyta zawartość pliku, a następnie wypisze na ekranie tylko te wiersze, w których znajduje się wyraz wprowadzony przez użytkownika.

W sumie nic trudnego ale jak na złość coś mi nie wychodzi. Oto mój kod:

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

bool szukaj( string Tekst, string szukanaFraza )
{
    cout << "test" << endl;
    size_t znalezionaPozycja = Tekst.find( szukanaFraza );
    if( znalezionaPozycja == string::npos )
         return false;
    else
         return true;
    
}

bool wczytanie_pliku( string & chcia_plik )
{
    ifstream plik;
    plik.open( chcia_plik.c_str() );
    if( !plik.good() )
    {
        return false;
    }
    
    string tekst;
    while( getline( plik, tekst ) )
    {
        cout << tekst << endl;
    }
    cout << endl;
    
    cout << "Jesli chcesz wyszukac fraze w tekscie podaj 'T', jesli nie, podaj 'N'" << endl;
    string podana;
    cin >> podana;
    cin.clear();
    cin.sync();
    if( podana == "T" )
    {
        cout << "Podaj fraze ktora chcesz wyszukac:\n";
        string a;
        getline( cin, a );
        while( std::getline( plik, tekst ) )
        {
            if( szukaj( tekst, a ) )
            {
                cout << tekst << endl;
            }
            else continue;
            
        }
    }
    
    plik.close();
    return true;
}


int main()
{
    do {
        cout << "Podaj nazwe pliku tekstowego ktory chcesz wczytac. Przykl.: 'x.txt' itp." << endl;
        cout << "Napisz 'end' jesli chcesz zakonczyc dzialanie programu." << endl;
        string chciany_plik;
        cin >> chciany_plik;
        cin.clear();
        cin.sync();
        string end = "end";
        if( chciany_plik == end )
        {
            return false;
        }
        cout << endl;
        
        if( !wczytanie_pliku( chciany_plik ) )
        {
            cout << "Nie znaleziono" << endl;
        }
    } while( true );
    
}

Problem pojawia się po podaniu literki T(zgadzamy się na wyszukiwanie frazy w tekście). Oto kod programu który sprawia mi problem:

 while( std::getline( plik, tekst ) )
        {
            if( szukaj( tekst, a ) )
            {
                cout << tekst << endl;
            }
            else continue;
            
        }

Za nic nie mogę pojąć co robię źle i czemu funkcja

szukaj(tekst, a)

nie działa, a uważam że nie działa bo wdrążyłem do niej instrukcję z cout-em który się nie wyświetla. Wiem że w zadaniu również wymagają aby została wyświetlona linijka tekstu w której znajduje się szukany wyraz ale chciałbym mimo to aby została wyświetlana pozycja na której się znajduje dane słowo.

Męczę się z tym jak skończony idiota od jakiś 4 dni i nie mogę sobie poradzić. Proszę o pomoc.

1

Po tym jak wczytasz dane z pliku to kursor jest "na końcu" i już nic więcej z pliku nie wczytasz!
Poza tym wczytywanie pliku wielokrotnie to jest zbrodnia. Weź łaskawie wczytaj cały plik do vector<string> a potem używaj już tylko tego vectora. Na przykład tak:

vector<string> lines;
copy(istream_iterator<string>(fileName), istream_iterator<string>(), back_inserter(lines));

i voila. Mamy vector w którym są kolejne linie z pliku. Teraz już tylko

for(string& line : lines){
    szukaj(line, tekst);
}

O ile dobrze napiszesz to szukaj to masz już cały program.

0

Dzięki za wytłumaczenie problemu i radę ale jestem świeżo upieczonym początkującym, vecotory wiele mi nie mówią, to dla mnie zupełna nowość z której za dobrze nie potrafię korzystać(praktycznie wcale, po prostu nie wiem jak się zachowa w programie) + ten dwukropek w instrukcji for " : " , nie wiem czy to wynika z jakiegoś braku biblioteki lub też błędnego zapisu który pozostawiłeś mi do poprawy ale kompilator sypie błędami, a na dodatek nie rozumiem co taki zapis oznacza.

2

Nie używaj kompilatorów z poprzedniego tysiąclecia.

2

Jeśli nie ma obsługi c++11 w Twoich narzedziach to "lypa". Konstrukcja którą dał @Shalom to range-based for loops ze standardu C++11 http://www.cprogramming.com/c++11/c++11-ranged-for-loop.html

Vectory możesz traktować jako lepsiejsze tablice. Albo inaczej - traktuj tablice jako ZŁOOOO i trzymaj się standardowych kontenerów.

3
bool szukaj( string Tekst, string szukanaFraza )
{
    cout << "test" << endl;
    size_t znalezionaPozycja = Tekst.find( szukanaFraza );
    if( znalezionaPozycja == string::npos )
         return false;
    else
         return true;
 
}

To jest całkiem sprawnie napisana funkcja szukająca, tylko:

  1. nie powinieneś przyjmować argumentów przez kopie. Tylko z nich czytasz, oba powinny być typu string const&.
  2. rozumiem, że ten wypisany "test" ma służyć debugowi, ale ani nie jest zbyt deskryptywny, ani jego wykonanie nie jest od trybu debug uzależnione.
  3. całą funkcję można skrócić do
return Tekst.find(szukanaFraza) != string::npos;

A zamiast wczytywać literkę jako string

    string podana;
    cin >> podana;
    cin.clear();
    cin.sync();
    if( podana == "T" )

spróbuj użyć typu znakowego:

    char podana;
    cin.clear();
    cin.sync();
    cin >> podana;
    if( podana == 'T' )

No i jak już chcesz się pobawić w pisanie grepa, to może popatrz na std::regex :)

0

Problem nareszcie rozwiązany, program działa tak jak tego oczekiwałem! Dziękuję bardzo za pomoc! :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1