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

Wyszukiwanie frazy w pliku - niepoprawny wynik [ROZWIĄZANY]

Ostatnio zmodyfikowano 2019-02-14 22:22
Autor Wiadomość
tirurir
Temat założony przez niniejszego użytkownika
» 2019-02-13 21:09:46
Narysuję sobie jutro algorytm na kartce papieru i na nowo się temu przyjrzę.
P-173959
tirurir
Temat założony przez niniejszego użytkownika
» 2019-02-14 18:37:54
Double posty co prawda nie są nigdy mile widziane ale post powstaje niemal dobę później i nie chciałbym aby przemknął ;)

Rozpisałem sobie dwie kartki oraz 1 wykres na code2flow i postanowiłem napisać funkcję od nowa. Pozbyłem się strlena, jest tam teraz zmienna length, pozostałe zmienne nadal mają takie same role ale nie stosuję już funkcji for. Łatwiej mi kontrolować licznik iteracji przy pętli while. Spróbowałem także dodać cofanie o którym mówiłeś stąd odejmuje ilość zgadzających się wcześniej znaków i dodaje 1.
Mam sprawny kod który wymaga naprostowania i wskazania drogi jak wyświetlać prawidłowy wynik. Najwyżej pozbędę się tej funkcji, wezmę jakiegoś gotowca i rozpiszę go sobie ale przyznam, że chciałem mieć satysfakcję z pisania jej samemu (i jak widać i tak nie wyszło bo przecież proszę o pomoc na forum). Miałem już różne wersje, zarówno takie jak ta które nic nie znajdują jak i takie które zawsze znajdą x powtórzeń nawet nie występującej frazy choć liczba ta nie jest stałą.

Aktualna funkcja

C/C++
int search( char arr[], int fileLen, char phrase[], int length ) //count all occurances of the phrase in arr
{
    int i = 0; //iteration counter
    int matchCount = 0; //matching characters counter
    int count = 0; //occarances counter
    while( i < fileLen )
    {
        if( arr[ i ] == phrase[ matchCount ] ) //letters match
        {
            matchCount++;
            i++;
            if( matchCount == length ) //whole phrase matches
            {
                count++;
                matchCount = 0; //set matchCount to 0, it has already done his job
            }
        }
        else //letters mismatch
        {
            i = i - matchCount + 1; //go a step furthers but do not forget about any possible phrase beginning
            matchCount = 0; //letters didn't match so the matchCount should be equal to 0
        }
       
    }
    return count;
}

Cały kod aby móc wygodnie wkleić do edytora:

C/C++
#define _CRT_SECURE_NO_WARNINGS //prevents 'use scanf_s warning' in Visual Studio
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
////////
int search( char arr[], int fileLen, char phrase[], int length ) //count all occurances of the phrase in arr
{
    int i = 0; //iteration counter
    int matchCount = 0; //matching characters counter
    int count = 0; //occarances counter
    while( i < fileLen )
    {
        if( arr[ i ] == phrase[ matchCount ] ) //letters match
        {
            matchCount++;
            i++;
            if( matchCount == length ) //whole phrase matches
            {
                count++;
                matchCount = 0; //set matchCount to 0, it has already done his job
            }
        }
        else //letters mismatch
        {
            i = i - matchCount + 1; //go a step furthers but do not forget about any possible phrase beginning
            matchCount = 0; //letters didn't match so the matchCount should be equal to 0
        }
       
    }
    return count;
}
////////
int main() {
    ////////VARIABLES (not including phrase)
    int count = 0;
    int i = 0;
    char buf[ 256 ]; //buffer for test input
    char arr[ 512 ]; // char arr[512];
    int fileLen = 512; //array (arr) size
    int length; //lenght of a phrase
    ////////OPEN FILE
    FILE * source;
    source = fopen( "D:file1.txt", "r" ); //open source
    while( fgets( arr, fileLen, source ) != NULL ); //read file.
    ////////ASK USER FOR TEXT TO FIND
    printf( "what phrase should i look for?\n\n" );
    scanf( "%s", buf );
    length = strlen( buf );
    printf( "Length of the typed phrase: %d,TEST\n", length ); //////TEST
    ////////WRITE FROM BUFFER TO PHRASE
    char * phrase = malloc( sizeof( char ) *( length + 1 ) ); //allocate memory fot phrase
    strncpy( phrase, buf, sizeof( phrase ) - 1 ); //uses strncpy the safe way
    phrase[ sizeof( phrase ) - 1 ] = '\0';
    printf( "You have typed: %s,TEST\n", phrase ); //////TEST
    ////////SEARCHING FOR THE PHRASE
    if( length <= fileLen )
    {
        count = search( arr, fileLen, phrase, length );
        printf( "I have found such phrase %d times.\n", count );
    }
    else
    {
        printf( "The phrase you have entered is longer than number of characters in the source file. Phrase was found 0 times.\n" );
    }
    ////////CLOSE
    fclose( source );
    system( "pause" );
    return 0;
}
P-173965
pekfos
» 2019-02-14 19:40:12
Nie rozumiem, z czym masz teraz problem, wiec tylko powytykam zauważone błędy.

C/C++
while( fgets( arr, fileLen, source ) != NULL ); //read file.

Tak nie wczytasz całego pliku, tylko ostatnią linię.

C/C++
////////WRITE FROM BUFFER TO PHRASE
char * phrase = malloc( sizeof( char ) *( length + 1 ) ); //allocate memory fot phrase
strncpy( phrase, buf, sizeof( phrase ) - 1 ); //uses strncpy the safe way
phrase[ sizeof( phrase ) - 1 ] = '\0';
printf( "You have typed: %s,TEST\n", phrase ); //////TEST
Po co to w ogóle robisz..? sizeof phrase zwraca rozmiar wskaźnika, nie zaalokowanej pamięci.
P-173968
tirurir
Temat założony przez niniejszego użytkownika
» 2019-02-14 20:28:24
C/C++
while( fgets( arr, fileLen, source ) != NULL ); //read file.

Zgodnie z opisem na qnx.com - fgets() wczytuje tekst aż spotka koniec linii bądź pliku. Z twojego komentarza myślałem, że może to jest problemem ale cały plik który wczytuję do programu składa się z jednej długiej linii tekstu.

To dziwne zastosowanie strcpy wziąłem z strcpy, strncpy, strcat i jak żyć - Gynvael Coldwind. Być może zrobiłem coś nie tak ponieważ zawsze szukając tej implementacji, zamiast wracać do filmu, szukam kodu w swojej ściągawce ćwiczeń które już wykonałem. Test printf który jest po kopiowaniu działa tak jak powinien w moim założeniu wyświetlając prawidłowo skopiowaną frazę.

Problem może być niezrozumiały ale zwyczajnie dostaję nieprawidłowy wynik z programu. Sprawdziłem oczywiście lokalizację i nazwę pliku i jest prawidłowa. Tekst posiada taką zawartość pastebin we wspomnianej pojedynczej linii.

Wybacz, że tak męczę ten jeden problem. Najwyżej przeniosę się z pliku na zadeklarowaną tablicę, a plikiem zajmę się innym razem.


=====
Wynik testu
Wynik testu
 
P-173970
pekfos
» 2019-02-14 21:55:47
Z twojego komentarza myślałem, że może to jest problemem ale cały plik który wczytuję do programu składa się z jednej długiej linii tekstu.
Więc po co ta pętla? Próbowałeś wypisać wczytany tekst?

Test printf który jest po kopiowaniu działa tak jak powinien w moim założeniu wyświetlając prawidłowo skopiowaną frazę.
A próbowałeś wpisać coś dłuższego niż parę znaków?
P-173971
tirurir
Temat założony przez niniejszego użytkownika
» 2019-02-14 22:22:01
Masz rację. Ucięło po siedmiu znakach. Naprawię w sobotę i dam znać, teraz czas zająć się nauką.
=============
Sobotni edit:
Kod śmiga tak jak powinien, wielkie dzięki za pomoc :) Przetestowałem fragmenty kodu w dwóch skróconych kompilacjach i po wrzuceniu ich do finalnego programu całość daje takie wyniki jakich się spodziewałem (nareszcie!). Poniżej kod dla wszystkich chętnych którzy widzieli ten wątek i chcieliby się mu przyjrzeć/skorzystać.

C/C++
#define _CRT_SECURE_NO_WARNINGS //prevents 'use scanf_s warning' in Visual Studio
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
////////
int search( char arr[], int fileLen, char phrase[], int length ) //count all occurances of the phrase in arr
{
    int i = 0; //iteration counter
    int matchCount = 0; //matching characters counter
    int count = 0; //occarances counter
    while( i < fileLen )
    {
        if( arr[ i ] == phrase[ matchCount ] ) //letters match
        {
            matchCount++;
            i++;
            if( matchCount == length ) //whole phrase matches
            {
                count++;
                matchCount = 0; //set matchCount to 0, it has already done his job
            }
        }
        else //letters mismatch
        {
            i = i - matchCount + 1; //go a step furthers but do not forget about any possible phrase beginning
            matchCount = 0; //letters didn't match so the matchCount should be equal to 0
        }
       
    }
    return count;
}
////////
int main() {
    ////////VARIABLES (not including phrase)
    int count = 0;
    int i = 0;
    char buf[ 256 ]; //buffer for test input
    char arr[ 512 ]; // char arr[512];
    int fileLen = 512; //array (arr) size
    int length; //lenght of a phrase
    ////////OPEN FILE
    FILE * source;
    source = fopen( "D:file1.txt", "r" ); //open source
    fgets( arr, fileLen, source );
    ////////ASK USER FOR TEXT TO FIND
    printf( "what phrase should i look for?\n\n" );
    scanf( "%s", buf );
    length = strlen( buf );
    printf( "Length of the typed phrase: %d,TEST\n", length ); //////TEST
    ////////WRITE FROM BUFFER TO PHRASE
    char * phrase = malloc( sizeof( char ) *( length + 1 ) ); //allocate memory fot phrase
    strncpy( phrase, buf, length ); //uses strncpy the safe way
    phrase[ length ] = '\0';
    printf( "You have typed: %s,TEST\n", phrase ); //////TEST
    ////////SEARCHING FOR THE PHRASE
    if( length <= fileLen )
    {
        count = search( arr, fileLen, phrase, length );
        printf( "I have found such phrase %d times.\n", count );
    }
    else
    {
        printf( "The phrase you have entered is longer than number of characters in the source file. Phrase was found 0 times.\n" );
    }
    ////////CLOSE
    fclose( source );
    system( "pause" );
    return 0;
}

P-173972
1 « 2 »
Poprzednia strona Strona 2 z 2