#include #include // структура объекта подстроки typedef struct Substring{ char *String; unsigned int Begin; unsigned int End; unsigned int Length; } Substring; // коллекция которая хранит в себе набор подстрок typedef struct SubstringCollection { Substring *Collection; unsigned int Count; } SubstringCollection; // метод для удаления подстроки из коллекции подстрок SubstringCollection RemoveFromCollection(SubstringCollection collection, int index) { for (int i = index; i < collection.Count - 1; i++) { collection.Collection[i] = collection.Collection[i+1]; } collection.Count--; collection.Collection = realloc(collection.Collection, sizeof(Substring) * (collection.Count + 1)); return collection; } // проверяем символ, заглавный ли он или нет _Bool isCapital(char c) { if((65 <= c) && (c <= 90)) { return 1; } return 0; } // возвращает любую часть строки начинающуюся и заканчивающуся на по номеру символа char* GetSubstring(char *inputString, unsigned int begin, unsigned int end) { unsigned int length = end - begin; char *substring = (char *) calloc(length + 1, sizeof(char)); for(int i = begin; i != end; i++) { substring[i - begin] = inputString[i]; } substring[length + 1] = '\0'; return substring; } // удалить русские символы с конца строки (может удалять что-то еще, я хз) Substring RemoveRussianSymbolsAtTheEnd(char *string, unsigned int stringLength) { for(int i = stringLength; i != 0; i--) { if (string[i] < 0) { stringLength--; } else if (string[i] > 0) break; } Substring result = { GetSubstring(string, 0, stringLength), (unsigned int) 0, stringLength, stringLength}; return result; } // проверить строку на наличие в ней скобок различного типа _Bool CheckForParentheses(char *string, unsigned int stringLength) { int parentheses[] = { 40, 41, 60, 62, 91, 93, 123, 125}; for(int i = 0; i != stringLength; i++) { for (int j = 0; j != 8; j++) { if (string[i] == parentheses[j]) return 1; } } return 0; } // найти одну подстроку выделенную латинскими заглавными символами Substring FindSubstring(char *inputString, unsigned int length) { unsigned int begin = 0; for(int i = 0; i <= length; i++) { if (isCapital(inputString[i]) && !isCapital(inputString[i + 1])) { begin = i + 1; break; } } inputString = GetSubstring(inputString, begin, length); unsigned int end = 0; for(int i = 0; i <= length - 1; i++) { if (!isCapital(inputString[i]) && isCapital(inputString[i + 1])) { end = i + 1; break; } } Substring result = { GetSubstring(inputString, 0, end), begin, begin + end, end }; return result; } // найти все подстроки в строке, выделенные латинскими заглавными символами SubstringCollection FindAllSubstrings(char *inputString, unsigned int length) { SubstringCollection collection; collection.Collection = malloc(sizeof(Substring) * 1); collection.Count = 0; do { Substring foundSubstring = FindSubstring(inputString, length); if (foundSubstring.Length == 0) { break; } else { collection.Collection = realloc(collection.Collection, sizeof(Substring) * (collection.Count + 1)); collection.Collection[collection.Count] = foundSubstring; inputString = GetSubstring(inputString, foundSubstring.End, length); length = length - foundSubstring.End; collection.Count++; } } while (1); return collection; } // простой нормальный человеческий метод для чтения из консоли, // чтобы не связываться с этим отвратительно мерзким scanf работающим через ... char* ReadLine(unsigned int bufferSize) { char* buffer = calloc(bufferSize, sizeof(char)); char symbol; unsigned int counter = 0; do { symbol = getchar(); if (symbol == '\n' || counter >= bufferSize) { break; } else { buffer[counter] = symbol; counter++; } } while (1); return buffer; } int main() { do { unsigned inputLength = 4096; char *inputLine; SubstringCollection collection; printf("\nEnter line:\n"); inputLine = calloc(inputLength, sizeof(char)); inputLine = ReadLine(inputLength); if (inputLine[0] == '\0') break; // ТЕСТОВАЯ СТРОКА: BEGIN usual text END BEGIN text with parentheses{ END BEGIN textwith russian at the endрусский текстEND collection = FindAllSubstrings(inputLine, inputLength); // создаем список для того, чтобы отметить элементы, которые мы будем удалять _Bool *RemoveItemList = calloc(collection.Count, sizeof(_Bool)); for (int i = 0; i != collection.Count; i++) { if (CheckForParentheses(collection.Collection[i].String, collection.Collection[i].Length) == 1) RemoveItemList[i] = 1; } // теперь после того, как мы определили подстроки, в которых есть скобки, мы удаляем их for (int i = collection.Count; i != 0; i--) { if (RemoveItemList[i] == 1) collection = RemoveFromCollection(collection, i); } // теперь пробегаемся по остаткам коллекции и удаляем элементы, у которых на конце есть русские символы, если они есть еще где-то, то они не удалятся for (int i = 0; i != collection.Count; i++) { collection.Collection[i] = RemoveRussianSymbolsAtTheEnd(collection.Collection[i].String, collection.Collection[i].Length); } // выводим этот хлам for (int i = 0; i != collection.Count; i++) { printf("%d). \"%s\"\n", i+1, collection.Collection[i].String); } } while (1); return 0; }