Поиск по маске, строки
Задача: написать функцию, которая по заданной строке и строковой маске создает в динамической памяти другую строку, содержащую список всех слов исходной строки, удовлетворяющих маске. Маска может содержать буквы, цифры и знак *
. Пример: маске 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;
}