Строка поиска не соответствует введенному тексту - PullRequest
1 голос
/ 05 марта 2020

У меня есть программа, которая будет соответствовать строке поиска (начинается с одной точки) во входной строке, но не будет работать для двух или более точек.

основная функция:

int main()
{
    int position;
    char input[255], pattern[255];

    printf("Please enter a line of text of up to 255 characters:\n");
    fgets(input,sizeof(input),stdin);
    input[strcspn(input, "\n")] = 0;

    printf("Please enter the search text of up to 255 characters:\n");
    fgets(pattern,sizeof(pattern),stdin);
    pattern[strcspn(pattern, "\n")] = 0;
    cmp(input, pattern);
    return 0;
}

функция cmp:

char cmp(char input[],char pattern[])
{

    int i, pattern_position, input_position;


    for(int pattern_position = 0; pattern_position < strlen(pattern); pattern_position++) {

        if(pattern[pattern_position] == '.'){
            char letter_space_comma[54] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ',', ' ', 'a', 'b', 'c', 'd', 'e', 'f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
            for (int  letter_space_comma_position= 0; letter_space_comma_position < 54; letter_space_comma_position++){
                pattern[pattern_position] = letter_space_comma[letter_space_comma_position];
                char *pos = strstr(input, pattern);
                if (pos) {
                    printf("Matches at position %ld.", pos-input);
                    goto end;
                }
            }
        }
    }

    char *pos = strstr(input, pattern);
    if (pos) {
        printf("Matches at position %ld.", pos-input);
    } else {
        printf("No match.");
    }

    end:
        return 0;
}

Вход 1 (1 точка):

Please enter a line of text of up to 255 characters: The cat sat on the mat.
Please enter the search text of up to 255 characters: .at

Выход 1 (правильный):

Matches at position 4.

Вход 2 (3) точки):

Please enter a line of text of up to 255 characters: The cat sat on the mat.
Please enter the search text of up to 255 characters: ...

Мой вывод 2:

No match.

Ожидаемый вывод 2:

Matches at position 0.

1 Ответ

1 голос
/ 05 марта 2020

Как предлагается в комментариях, вы должны использовать отладчик и проверять различные значения, взятые pattern строкой в ​​функции cmp:

for (int  letter_space_comma_position= 0; letter_space_comma_position < 54; letter_space_comma_position++){
    pattern[pattern_position] = letter_space_comma[letter_space_comma_position];

    /* HERE */ 

    char *pos = strstr(input, pattern);

Когда у вас есть один "любой символ", вы тестируете все возможности.

Когда у вас есть два, например ..t, вы тестируете a.t, b.t ... z.t, затем zat, zbt ... zzt.


Один простой способ сделать то, что вы хотите, - это использовать рекурсивность:

  1. подготовить новый шаблон для проверки первого найденного символа '.'
  2. отправьте этот новый шаблон в вызывающий вызов.

Но это предполагает некоторые изменения в вашей cmp функции:

  • it must скажите (по возвращаемому значению), если он нашел совпадение
  • , он не должен печатать, когда совпадение не найдено (потому что он будет вызываться много раз)
  • он не должен изменять pattern передан параметр: он должен иметь свою собственную копию.

С учетом этих элементов одной реализацией может быть:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char * cmp(char input[],char pattern[])
{
    int i, pattern_position, input_position;

    for(int pattern_position = 0; pattern_position < strlen(pattern); pattern_position++) {

        if(pattern[pattern_position] == '.'){

            /* make a local copy of pattern */
            char * pat = strdup(pattern);
            char * ret;

            char letter_space_comma[54] = {'A', 'B', 'C', ... 's','t','u','v','w','x','y','z'};
            for (int  letter_space_comma_position= 0; letter_space_comma_position < 54; letter_space_comma_position++){
                pat[pattern_position] = letter_space_comma[letter_space_comma_position];


                ret = cmp(input, pat);
                if (ret)
                    /* if some match, do not test other possibilities:
                     * exist for loop, but not the function: you must free pat */
                    break;

            }
            /* free the local copy */
            free(pat);

            if (ret)
                /* match happened and mem freed: we can leave the function*/
                return ret;
        }
    }

    char *pos = strstr(input, pattern);
    if (pos) {
        printf("match at %ld\n", pos - input);
        return pos;
    }

    end:
        return 0;
}

I добровольно нет t слишком сильно изменил свой код, так что вы все равно можете поработать над ним и научиться:

  • удалить printf из cmp и отобразить окончательный результат из main ("match" / "no match ")
  • сделать letter_space_comma постоянным и статическим c: это не причина устанавливать столько времени.
  • изменение прототипа cmp для предотвращения изменения строк input и pattern.
  • упрощение (удаление бесполезной переменной, примечания, что в cmp вы можете напрямую вернуть результат strstr ....)
...