Wyszukiwanie słów w pliku tekstowym

Bash, C, C++, Java, PHP, Ruby, GTK, Qt i wiele innych - wszystko tutaj.
OncioTat
Piegowaty Guziec
Piegowaty Guziec
Posty: 10
Rejestracja: 29 paź 2012, 15:38
Środowisko graficzne: Unity
Architektura: x86_64

Wyszukiwanie słów w pliku tekstowym

Post autor: OncioTat »

Witajcie.
Potrzebuję pomocy przy napisaniu programu, który ma za zadanie przeszukać plik tekstowy i wyszukać w nim dane słowo.
Mam taki kod:

Kod: Zaznacz cały

#include <iostream>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/mman.h>

using namespace std;

int main(int argc, char *argv[])
{
    int fd;
    struct stat plik;
    size_t ile_bajtow;
    char *mapa;
    string wyraz;
    fd = open("tekst", O_RDWR);
        if(fd == -1)
            cout << "Nie udało się otworzyć pliku.\n";
        else
            cout << "Hurra!!!\n";
    fstat(fd, &plik);
    cout << "Rozmiar pliku: " << plik.st_size << "\n";
    mapa = (char*)mmap(NULL, plik.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    cout << "Podaj wyraz do wyszukania: ";
    cin >> wyraz;
    int n = wyraz.size();
    char bufor[n];
    ile_bajtow = n;
    int x = plik.st_size;
    if(x < n)
        cout << "Plik ma mniejszy rozmiar niż poszukiwany wyraz.\n";
    else
         read(fd, bufor, ile_bajtow);
                if(bufor == wyraz) <-- Tutaj coś nie działa tak jak bym oczekiwał. ???
                    cout << bufor;
                else
                    cout << "$$$$$$$$ blada\n";
    return 0;
}
Gdy wczytane słowo jest takie samo jak w buforze, to i tak bufor != wyraz i wyświetla mi to co jest w else.. Dlaczego?
Czy trzeba zamienić zmienną typu string na tablicę znaków? Z góry dziękuję za pomoc. :)
Awatar użytkownika
beluosus
Zakręcona Traszka
Zakręcona Traszka
Posty: 695
Rejestracja: 01 paź 2006, 15:32
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: Xfce
Architektura: x86
Kontakt:

Re: Wyszukiwanie słów w pliku tekstowym

Post autor: beluosus »

Dlaczego? Nie dajesz null-terminatora na koniec bufora.

Jeśli nie masz absolutnej konieczności korzystania z open/read i możesz skorzystać z streamów to skorzystaj. Program zamknie się w 5 liniach bez niebezpiecznego zarządzania pamięcią (co doprowadziło do błędu...).

PS
Mam nadzieję, że wiesz, że po if(x < n) zostanie wykonany kod pod read (brak nawiasów {}).
OncioTat
Piegowaty Guziec
Piegowaty Guziec
Posty: 10
Rejestracja: 29 paź 2012, 15:38
Środowisko graficzne: Unity
Architektura: x86_64

Re: Wyszukiwanie słów w pliku tekstowym

Post autor: OncioTat »

beluosus pisze:Nie dajesz null-terminatora na koniec bufora.
A jak powinno to wyglądać z NULL terminatorem?
beluosus pisze: Jeśli nie masz absolutnej konieczności korzystania z open/read i możesz skorzystać z streamów to skorzystaj. Program zamknie się w 5 liniach bez niebezpiecznego zarządzania pamięcią (co doprowadziło do błędu...).
Muszę skorzystać z mmap(), taki jest warunek. Jako że jestem świeżakiem Linuxowym to szukam w trakcie pisania jakie funkcje mogą wykonać postawione zadanie. O stream-ach zaraz postaram się coś poczytać.
beluosus pisze:Mam nadzieję, że wiesz, że po if(x < n) zostanie wykonany kod pod read (brak nawiasów {}).
Tak, wiem. To nie jest jeszcze nawet blisko końca, tak napisałem żeby sprawdzić czy uda się wczytać pierwsze kilka bajtów pliku do bufora i porównać z wcześniej wczytanym słowem, no i klops.
Awatar użytkownika
beluosus
Zakręcona Traszka
Zakręcona Traszka
Posty: 695
Rejestracja: 01 paź 2006, 15:32
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: Xfce
Architektura: x86
Kontakt:

Re: Wyszukiwanie słów w pliku tekstowym

Post autor: beluosus »

Kod: Zaznacz cały

	char *bufor = new char[n + 1]; // ISO C++ nie pozwala na używanie zmiennej do określania wielkości tablic
//...
	{
		read(fd, bufor, n);
		bufor[n] = '\0';
	}
//...
	delete [] bufor; // jak już nie będziemy używać
	bufor = NULL;
Awatar użytkownika
ethanak
Wygnańcy
Posty: 3054
Rejestracja: 04 gru 2007, 13:19
Płeć: Mężczyzna
Wersja Ubuntu: 12.04
Środowisko graficzne: GNOME
Architektura: x86
Lokalizacja: Bielsko-Biała
Kontakt:

Re: Wyszukiwanie słów w pliku tekstowym

Post autor: ethanak »

beluosus pisze:ISO C++ nie pozwala na używanie zmiennej do określania wielkości tablic
A z czystej ciekawości: alloca można używać?
OncioTat
Piegowaty Guziec
Piegowaty Guziec
Posty: 10
Rejestracja: 29 paź 2012, 15:38
Środowisko graficzne: Unity
Architektura: x86_64

Re: Wyszukiwanie słów w pliku tekstowym

Post autor: OncioTat »

@beluosus
Wielkie dzięki, teraz działa :ligt:
Walczę dalej...
Awatar użytkownika
Yuri20
Sędziwy Jeż
Sędziwy Jeż
Posty: 49
Rejestracja: 31 maja 2009, 13:35
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: KDE Plasma
Architektura: x86_64

Re: Wyszukiwanie słów w pliku tekstowym

Post autor: Yuri20 »

Z wyrażeń regularnych warto by skorzystać.
Awatar użytkownika
mucha090
Zakręcona Traszka
Zakręcona Traszka
Posty: 775
Rejestracja: 15 mar 2008, 11:05
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: Brak
Architektura: x86_64
Lokalizacja: Kielce, Poland
Kontakt:

Re: Wyszukiwanie słów w pliku tekstowym

Post autor: mucha090 »

@OncioTat
hehe a jeśli to co piszesz ma być w c++ to prosze, oto funkcja która tobie się przyda
http://wklej.org/id/876890/
ona wyszuka tobie to co chcesz
przyda się jeśli robisz plik konfiguracyjny :D
mam nadzieje że przyda tobie się no i plik który chcesz odczytać jest plikiem tekstowym a nie binarnym:P
OncioTat
Piegowaty Guziec
Piegowaty Guziec
Posty: 10
Rejestracja: 29 paź 2012, 15:38
Środowisko graficzne: Unity
Architektura: x86_64

Re: Wyszukiwanie słów w pliku tekstowym

Post autor: OncioTat »

@mucha090
Dzięki, ale muszę użyć mmap();
Stanąłem w jednym miejscu i nie mogę tego przeskoczyć. Program wyewoluował do takiej oto postaci:

Kod: Zaznacz cały

#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/mman.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

using namespace std;
/*
Napisać program:

    chcase plik słowo

który wyszukuje wszystkie wystąpienia podanego "słowa" w pliku
wejściowym i zapisuje "SŁOWO" dużymi literami. Wykorzystać funkcję
mmap().
*/
int main(int argc, char *argv[])
{
    int fd, x, p = 0;
    struct stat plik;
    void *mapa;
    char *bufor, *bufor2, *bufor3, *slowo;
    argv[1] = "tekst";  //<-- tak nie powinno być, docelowo program ma być uruchamiany z argumentami
    if(argc != 3)
        {
        perror("Zła liczba parametrów. Poprawna składnia to: nazwa [plik] [słowo]");
        }
    if((fd = open(argv[1],O_RDWR|O_RDONLY)) == -1)
        {
        perror("Błąd pliku");
        return 1;
        }
    if(fstat(fd,&plik))
        {
        perror("Błąd fstat");
        return 1;
        }
    if((mapa = mmap(NULL, plik.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == (void*) -1)
        {
        perror("Błąd mmap");
        return 1;
        }
    argv[2] = "oncio";  //<-- tu też
    slowo = argv[2];    // <-- tak nie działa :(
    bufor = (char*)malloc(1);
    bufor2 = (char*)malloc(slowo.size());
    bufor3 = (char*)malloc(1);
    x = plik.st_size;
    if(x < slowo.size())
        cout << "Plik ma mniejszy rozmiar niż poszukiwany wyraz.\n";
    else
        for(int i = 0; i < plik.st_size; i++)
            {
            memcpy(bufor, mapa + i, 1);
                if(*bufor == slowo[p])
                    {
                    bufor2[p] = *bufor;
                    p++;
                    }
                else
                    p = 0;
                if(bufor2 == slowo)
                    {
                    memcpy(bufor3, mapa + i - slowo.size(), 1);
                    memcpy(bufor, mapa + i + 1, 1);
                    if((*bufor==' '||*bufor==','||*bufor=='.'||*bufor=='!'||*bufor=='?'||*bufor=='\"')&&(*bufor3==' '||*bufor3==','||*bufor3=='.'||*bufor3=='!'||*bufor3=='?'||*bufor3=='\"'))
                        {
                        for(int j = 0; j < slowo.size(); j++)
                        if(bufor2[j] >= 'a' && bufor2[j] <= 'z')
                            {
                            bufor2[j] += ('A' - 'a');
                            }
                        lseek(fd, i - slowo.size() + 1, SEEK_SET);
                        write(fd, bufor2, slowo.size());
                        p = 0;
                        }
                    }
            }
    close(fd);
    free(bufor);
    free(bufor2);
    free(bufor3);
    munmap(0, plik.st_size);
    return 0;
}
Problem w tym że nie wiem jak wyłuskać ile znaków ma słowo podane przez użytkownika jako drugi argument. Ze stringiem nie ma problemu jest string.size() ale z *argv[] ???? Jak to ugryźć???
Awatar użytkownika
ethanak
Wygnańcy
Posty: 3054
Rejestracja: 04 gru 2007, 13:19
Płeć: Mężczyzna
Wersja Ubuntu: 12.04
Środowisko graficzne: GNOME
Architektura: x86
Lokalizacja: Bielsko-Biała
Kontakt:

Re: Wyszukiwanie słów w pliku tekstowym

Post autor: ethanak »

Może jednak sięgniesz do podstaw? Za chwilę się okaże że nie wiesz gdzie na klawiaturze jest enter...
Włączasz do swojego programu string.h - może sobie uprzejmie przejrzysz podręcznik:

Kod: Zaznacz cały

man string
zamiast robić coś bezmyślnie a potem jęczeć na forum że czegoś nie wiesz.
BTW. hydraulik to bardzo szacowny i i dający niezłe dochody zawód. Sprzedawca pietruszki też... potraktuj to jako delikatną sugestię.
OncioTat
Piegowaty Guziec
Piegowaty Guziec
Posty: 10
Rejestracja: 29 paź 2012, 15:38
Środowisko graficzne: Unity
Architektura: x86_64

Re: Wyszukiwanie słów w pliku tekstowym

Post autor: OncioTat »

Nie ładnie tak obrażać innych na publicznym forum kolego ethanek. Jestem początkujący i wielu rzeczy nie wiem dlatego się uczę. Może i zrobię coś bezmyślnie ale to nie znaczy że możesz komuś ubliżać na publicznym forum. :-x
Awatar użytkownika
ethanak
Wygnańcy
Posty: 3054
Rejestracja: 04 gru 2007, 13:19
Płeć: Mężczyzna
Wersja Ubuntu: 12.04
Środowisko graficzne: GNOME
Architektura: x86
Lokalizacja: Bielsko-Biała
Kontakt:

Re: Wyszukiwanie słów w pliku tekstowym

Post autor: ethanak »

niestety - programowanie wymaga myślenia. przykre - ale prawdziwe.
przy okazji - znalazłeś już strlen czy czekasz aż ktoś znajdzie za ciebie?

a tak w ogóle to w którym miejscu ci ubliżyłem?
OncioTat
Piegowaty Guziec
Piegowaty Guziec
Posty: 10
Rejestracja: 29 paź 2012, 15:38
Środowisko graficzne: Unity
Architektura: x86_64

Re: Wyszukiwanie słów w pliku tekstowym

Post autor: OncioTat »

ethanak pisze:niestety - programowanie wymaga myślenia.
Uważasz że da się cokolwiek napisać bez myślenia? To znaczy że jestem geniuszem :ligt:
ethanak pisze: przy okazji - znalazłeś już strlen czy czekasz aż ktoś znajdzie za ciebie?
Tak, znalazłem dziękuję.
ethanak pisze:a tak w ogóle to w którym miejscu ci ubliżyłem?
Hmmm, może przewrażliwiony jestem.
ODPOWIEDZ

Wróć do „Programowanie”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 12 gości