Pomoc przy wyrazeniach regularnych

0

Siemka!
Otoz ostatnio znalazlem dosyc ciekawe zadanie, ktore ma za zadanie w danym slowie znalezc odpowiednia fraze.
Moj kod wyglada nastepujaco:

 int main (int argc, char** argv)
{

    char input_string[100], search_pattern[50], matching_substring[100];
    int i=0;
    int j =0;
    int k=0;
    int m = 0;
    char current_char;

    /////////////////////////////////////////////

    print_string("Zdanie: ");

    do
    {
        current_char=read_char();
        input_string[i]=current_char;
        i++;
    }
    while (current_char != '\n');
    int input = i-1;
    printf("%d",input);

    /////////////////////////////////////////////

    while(1)
    {

        i=0;

        print_char('\n');

        print_string("Czego szukasz: ");

        do
        {
            current_char=read_char();
            search_pattern[i]=current_char;
            i++;
        }
        while (current_char != '\n');
        int sp = i-1;
        printf("%d ",sp);
        /////////////////////////////////////////////
        i=0;
        k=0;
        while (i<input)
        {
            j=0;
            if (input_string[i]==search_pattern[j])
            {
                while (search_pattern[j]!='\n'&&input_string[i]==search_pattern[j])
                {
                    matching_substring[k] = input_string[i];
                    k++;
                    i++;
                    j=j+1;;

                }
                if (j==sp)
                {
                    matching_substring[k] = '#';
                    k++;
                }
                else
                {
                    for (m=0; m<100; m++)
                    {
                        matching_substring[m] = '\0';

                    }

                }



            }
            else
            {
                i++;
            }
        }

        print_string("Rezultat: ");
        for (m = 0; m < 100; m++)
        {
            if (matching_substring[m] =='#'&&matching_substring[m+1] == '\0') {
                matching_substring[m] = '\0';
            }
            if (matching_substring[m] != '\0'||matching_substring[m] != '\n')
            {
                print_char(matching_substring[m]);
            }
            else
            {
                break;
            }
        }
        for (m=0; m<100; m++)
        {
            matching_substring[m] = '\0';

        }

        print_char('\n');

        /////////////////////////////////////////////

    }

    return 0;
}

Niestety, ten kod nie dziala w przypadku gdy zdanie jest "hhh" a fraza szukana "hh". Wynik powinien byc hh#hh. Zamiast przecinka uzywam # do oddzielenia. Moglby ktos mi ewentualnie pomoc z wprowadzeniem poprawek, lub zasugerowac lepsza metode?

0

Zacznij od czytelności. Znaleźć coś w tym kodzie to niezłe wyzwanie:

  1. masz kawałki kodu pooddzielane komentarzem. To dosyć jasny znak, że powinieneś podzielić w tych miejscach funkcję na mniejsze. Dzięki temu kawałki kodu będą nazwane. Generalnie łatwiej jest czytać kod o którym ma się pojęcie co robi, a w funkcji głównej będziesz miał ładny opis problemu bliski językowi naturalnemu.
  2. Wydaje mi się że na samym początku inmplementujesz funkcję fgets ze string.h, użyj tej funkcji. Również nie wiadomo co to jest read_char, to nie jest stadnard. Chodzi o fgetc na standardowym wejściu?
  3. Szanuję swoje nerwy więc dalej sobie darowałem, ale z opisu problemu wnioskuję, że chcesz sprawdzić, czy b jest podciągiem a.... Służy do tego funkcja strstr() ze string.h Dla celów edukacyjnych przykładowa implementacja:
 
#include <stdio.h>
#include <stdbool.h>
#include <string.h>

const char * find_substring( const char *base, const char *substring ){
    bool found = false;
    while( *base != '\0' && !found ){
        const char *substring_cursor = substring;
        const char *base_cursor = base;
        while( *base_cursor != '\0' && *substring_cursor == *base_cursor ){
            substring_cursor++;
            base_cursor++;
        }

        if( *substring_cursor == '\0' )
            found = true;
        else
            base++;
    }
    
    if( found )
        return base;
    else
        return NULL;
}

int main( int argc, char **argv ){
    char base[50];
    char substring[50];

    fgets( base, 50, stdin );
    base[strlen(base)-1] = '\0';
    fgets( substring, 50, stdin );
    substring[strlen(substring)-1] = '\0';

    char *match = find_substring( base, substring );
    if( match == NULL )
        printf( "Nie odnaleziono wzorca.\n" );
    else{
        unsigned int position = (unsigned int) (match-base);
        printf( "Odnaleziono na pozycji %u.\n", position );
    }
    return 0;
}

typ bool pochodzi z stdbool.h i jest częścią standardu C99. Jeśli używasz starszego, powinieneś użyć int i wówcas 0=fałsz, pozostałe to prawda. Podobnie standard ten znosi wymóg, żeby wszystkie zmienne były definiowane na początku bloku. I skoro już pzzy C99 jesteśmy, można się też pokusić o słowo kluczowe restrict przy parametrach funkcji find_substring, ale już zostawiłem bez.

0
  1. To oddzielenie sluzy, aby rozroznic "i" w posczegolnych stringach, zebym lepiej zrozumial, gdzie jest input, gdzie drugie pytanie. Po 3 komentarzu jest sam program i output/
  2. Niestety, musze korzystac z read_char(),poniewaz potem bedzie ten program tlumaczony na jezyki Asemblera, gdzie dla czytelnosci i szybszego tlumaczenia, uzywa sie "read char"
  3. Dokladnie, cos w tym stylu. Wiem, ze blad jest w miejscu, gdzie for (m=0.....). Tam resetuje sie caly array, ale nie powinien, wiec chyba tam ejst potrzebny jakis case.
0

Na assembler? Bierzesz GCC z przełączynikiem -S i zrobione. :D
A jeśli nie i ktoś ma ten kod w assemblerze czytać to tym bardziej dobrze zorganizuj kod, bo jak w C nie wiadomo o co chodzi to w assemblerze to już będzie katastrofa. ;) Swoją drogą w assemlerze można używać bibliotek. Swojego czasu nawet w WinApi pisałem z poziomu assemblera. :)

1

Słyszałeś o funkcji strstr? http://en.cppreference.com/w/c/string/byte/strstr

0

Elwis: Niestety, jest to specifyczny assembler: MIPS. Twoja metoda owszem dziala, ale nie tlumaczy danego programu na moje wymagania. O ile mi wiadomo, MIPS nie posiada bibliotek.
Kq: O danej funkcji slyszalem, ale ten program ma byc jak najprostszy, aby MIPS byl jak najlatwiejszy. Jezeli uzyje funkcji, trzeba bedzie ja zdefiniowac w MIPSie.

1

Trzeba było mówić, że nie masz dostępu do biblioteki standardowej.
W takim razie zaimplementuj/użyj strncmp, od tego momentu implementacja własnego strstr jest trywialna.

0
Świetny Pomidor napisał(a):

Elwis: Niestety, jest to specifyczny assembler: MIPS. Twoja metoda owszem dziala, ale nie tlumaczy danego programu na moje wymagania. O ile mi wiadomo, MIPS nie posiada bibliotek.
Kq: O danej funkcji slyszalem, ale ten program ma byc jak najprostszy, aby MIPS byl jak najlatwiejszy. Jezeli uzyje funkcji, trzeba bedzie ja zdefiniowac w MIPSie.

Trzeba było od razu tak pisać. Niemniej jednak są kompilatory C dla tej architektury z tego co wiem, więc może się obejść nawet bez assemblera. Co do funkcji, strstr ci napisałem, prostego fgetsa sam sobie napisałeś. Wszystko gra. :)

0

elwis: probowalem znalezc, ale nic z tego :/ Jesli chodzi o kod, to cos zmienilem i kod dziala dla wiekszosci przypadkow, sa jednak wyjatki np. hello i lo, nic nie pokazuje.

int main (int argc, char** argv)
{

    char input_string[100], search_pattern[50], matching_substring[100];
    int i=0;
    int j =0;
    int k=0;
    int m = 0;
    char current_char;

    /////////////////////////////////////////////

    print_string("input: ");

    do
    {
        current_char=read_char();
        input_string[i]=current_char;
        i++;
    }
    while (current_char != '\n');
    int input = i-1;
    printf("%d",input);

    /////////////////////////////////////////////

    while(1)
    {

        i=0;

        print_char('\n');

        print_string("search pattern: ");

        do
        {
            current_char=read_char();
            search_pattern[i]=current_char;
            i++;
        }
        while (current_char != '\n');
        int sp = i-1;
        printf("%d ",sp);
        /////////////////////////////////////////////
        i=0;
        k=0;
        while (i<input)
        {
            j=0;
            if (input_string[i]==search_pattern[j])
            {
                while (search_pattern[j]!='\n'&&input_string[i]==search_pattern[j])
                {
                    matching_substring[k] = input_string[i];
                    k++;
                    i++;
                    j=j+1;;

                }
                if (j==sp)
                {
                    matching_substring[k] = '#';
                    k++;
                }
                else
                {
                    m=100;   //TU ZMIENILEM
                    while (m>=0) {
                        while (matching_substring[m]!='#') {
                                matching_substring[m]='\0';
                                m--;
                        }
                        if (matching_substring[m]=='#') {
                                matching_substring[m]='\0';
                                break;
                        }
                    }


                }



            }
            else
            {
                i++;
            }
        }

        print_string("output: ");
        for (m = 0; m < 100; m++)
        {
            if (matching_substring[m] =='#'&&matching_substring[m+1] == '\0') {
                matching_substring[m] = '\0';
            }
            if (matching_substring[m] != '\0'||matching_substring[m] != '\n')
            {
                print_char(matching_substring[m]);
            }
            else
            {
                break;
            }
        }
        for (m=0; m<100; m++)
        {
            matching_substring[m] = '\0';

        }

        print_char('\n');

        /////////////////////////////////////////////

    }

    return 0;
} 

Program kasuje tylko do ostatniego # lub do konca arraya, jesli # nie ma. Natomiast problemem jest tak jak wspomnialem wczesniej hello i lo, nie pokazuje outputa

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