Поиск по маске, строки

Рейтинг: 0Ответов: 0Опубликовано: 10.04.2023

Задача: написать функцию, которая по заданной строке и строковой маске создает в динамической памяти другую строку, содержащую список всех слов исходной строки, удовлетворяющих маске. Маска может содержать буквы, цифры и знак *. Пример: маске c*p* соответствуют слова cp, cap, clip, couple, champion и т.д. Да, пустая последовательность тоже может удовлетворять маске. Проблема: код работает, но на отдельных тестовых данных все ломается, вместо соответствующей последовательности получается несуразица из символов. Я так понимаю, что нужно добавить проверку, которая будет выкидывать все, что не является цифрами и буквами, но пока корректно это сделать не получилось (очевидно, как должна выглядеть сама проверка, но куда именно ее оптимально поставить я не понимаю). Если я не права, и проблема в ином, ткните, пожалуйста, носом.

P.S. библиотеку string.h использовать нельзя

#include <stdio.h>
#include <stdlib.h>
 
char* ReadLine(void) {
    int length = 0;
    char* paragraph = (char*)malloc(sizeof(char));
    char c = getchar();
    while (c != '\n') {
        paragraph[length++] = c;
        paragraph = (char*)realloc(paragraph, sizeof(char) * (length + 1));
        c = getchar();
    }
    paragraph[length] = '\0';
    return paragraph;
}
 
char* ReadParagraph(void) {
    int length = 0;
    char* paragraph = (char*)malloc(sizeof(char));
    char c = getchar();
    while ((c != '\n') || (paragraph[length - 1] != '\n')) {
        paragraph[length++] = c;
        paragraph = (char*)realloc(paragraph, sizeof(char) * (length + 1));
        c = getchar();
    }
    paragraph[length] = '\0';
    return paragraph;
}
 
int FindLength(const char* str) {
    int i;
    for (i = 0; str[i] != '\0'; ++i);
    return i;
}
 
//str1=str1+str2
char* add_str_to_str(char* str1, const char* str2) {
    int length1 = FindLength(str1);
    int length2 = FindLength(str2);
    str1 = (char*)realloc(str1, sizeof(char) * (length1 + length2 + 1));
    for (int i = 0; i < length2; ++i) {
        str1[length1 + i] = str2[i];
    }
    str1[length1 + length2] = '\0';
    return str1;
}
 
//append str to array of str
char** append(char** array_of_strings, int size_of_array, char* new_string) {
    array_of_strings = (char**)realloc(array_of_strings, sizeof(char*) * (size_of_array + 1));
    array_of_strings[size_of_array] = new_string;
    return array_of_strings;
}
 
//make list of mask substrings
char** spisok(const char* mask, int* length) {
    int len = FindLength(mask);
    int size_of_comb = 0;
    char** comb = (char**)malloc(0);
    for (int i = 0; i < len; ++i) {
        char* a = (char*)malloc(sizeof(char));
        a[0] = '\0';
        while (mask[i] != '*' && i < len) {
            char temp[] = { mask[i], '\0' };
            a = add_str_to_str(a, temp);
            ++i;
        }
        if (FindLength(a) > 0) {
            comb = append(comb, size_of_comb++, a);
        }
        else {
            free(a);
        }
    }
    *length = size_of_comb;
    return comb;
}
 
//find str2 in str1
int StrFind(char const* str1, char const* str2, int k) {
    int len1 = FindLength(str1);
    int len2 = FindLength(str2);
    int j = 0;
    for (int i = k; i < len1; ++i) {
        if (str1[i] == str2[j]) {
            ++j;
            if (j == len2) {
                return i;
            }
        }
        else {
            j = 0;
        }
    }
    return -1;
}
 
//check if word satisfies mask
int CheckMask(const char* str, char const* mask) {
    int size;
    char** c = spisok(mask, &size);
    if (size == 0) {
        return 1;
    }
    if (mask[0] != '*' && StrFind(str, c[0], 0) != FindLength(c[0]) - 1) {
        return 0;
    }
    int k = FindLength(c[0]) - 1;
    for (int i = 1; i < size - 1; ++i) {
        k = StrFind(str, c[i], k + 1);
        if (k == -1) {
            return 0;
        }
    }
    int str_len = FindLength(str);
    if (mask[FindLength(mask) - 1] != '*' && StrFind(str, c[size - 1], str_len - FindLength(c[size - 1])) == -1) {
        return 0;
    }
    return 1;
}
 
char* FindMaskWords(const char* line, const char* mask) {
    char* result = (char*)malloc(sizeof(char));
    result[0] = '\0';
    int length = FindLength(line);
    int i = 0;
    int end = 0;
    while (i < length) {
        while (line[i] != ' ' && line[i] != '\n' && i < length) {
            ++i;
        }
        ++i;
        char* temp = malloc(sizeof(char) * (i - end));
        for (int j = end; j < i - 1 && temp[0] != ' ' && temp[0] != '\n' && j < length; ++j) {
            temp[j - end] = line[j];
        }
        temp[i - end - 1] = '\0';
        if (CheckMask(temp, mask) && temp[0] != ' ' && temp[0] != '\n') {
            result = add_str_to_str(result, temp);
            add_str_to_str(result, ", ");
        }
 
        free(temp);
        end = i;
    }
    if (result[0] != '\0') {
        result[FindLength(result) - 2] = '\0';
    }
    return result;
}
 
int main() {
    char* mask = ReadLine();
    char* line = ReadParagraph();
    char* c = FindMaskWords(line, mask);
    printf("%s", c);
    free(c);
    return 0;
}

Ответы

Ответов пока нет.